| /* ******************************** |
| * Author: Warren |
| * License: MobileTek |
| *//** @file timeManagement.h link.h*//* |
| * |
| ********************************/ |
| #include <stdio.h> |
| #include <pthread.h> |
| #include <stdint.h> |
| #include <semaphore.h> |
| #include <sys/time.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <log/log.h> |
| #include "thpool.h" |
| #include "timeManagement.h" |
| #include "link.h" |
| #define LOG_TAG "LYNQ_TIME_MAN" |
| |
| int cond_length = 0; |
| cond_used_state cond_array[CONDARRAYMAX]={0}; |
| COND_NODE* COND_HEAD; |
| pthread_mutex_t len_mutex; |
| extern timerArgv * timerArgv_t = NULL; |
| int taskWorking = 0; |
| pthread_mutex_t task_Mutex = PTHREAD_MUTEX_INITIALIZER; |
| pthread_cond_t task_Cond = PTHREAD_COND_INITIALIZER; |
| |
| int initCondArray(void) |
| { |
| for(int i = 0;i<CONDARRAYMAX;i++) |
| { |
| cond_array[i].state = 0; |
| cond_array[i].index = i; |
| cond_array[i].use_state = 0; |
| pthread_mutex_init(&(cond_array[i].mutex), NULL); |
| pthread_cond_init(&(cond_array[i].cond), NULL); |
| } |
| return 0; |
| } |
| cond_used_state* findUnusedCond(cond_used_state cond_array[],int arraLength) |
| { |
| for(int i =0;i<arraLength;i++) |
| { |
| if((cond_array[i].state==0)&&(cond_array[i].use_state==0)) |
| { |
| return &cond_array[i]; |
| } |
| } |
| return NULL; |
| } |
| |
| int millli_sleep_with_restart(int millisecond) |
| { |
| int left = millisecond*1000; |
| while (left > 0) |
| { |
| left = usleep(left); |
| } |
| |
| return 0; |
| } |
| int micro_sleep_with_restart(int microseconds) |
| { |
| int left = microseconds; |
| while (left > 0) |
| { |
| left = usleep(left); |
| } |
| return 0; |
| } |
| |
| void startWaitResp(void *arg) |
| { |
| struct timeval now; |
| struct timespec outtime; |
| request_cond* param = (request_cond*)arg; |
| int num = param->cond_index; |
| int time = param->waitTime; |
| RLOGD("[Warren test] index is %d\n",num); |
| RLOGD("[Warren test] thread 0x%x working on task %d\n",(unsigned int)pthread_self(),num); |
| int ret = 0; |
| gettimeofday(&now, NULL); |
| outtime.tv_sec = now.tv_sec + time; |
| //outtime.tv_nsec = now.tv_usec * 1000; |
| while (cond_array[num].state==0) |
| { |
| RLOGD("[Warren test]cond_length is %d\n",cond_length); |
| if(cond_length<CONDARRAYMAX) |
| { |
| pthread_mutex_lock(&len_mutex); |
| cond_length++; |
| COND_HEAD = addCondLinkNode(COND_HEAD,param->token, cond_array[num].index,cond_array[num].cond); |
| taskWorking=0; |
| pthread_cond_signal(&task_Cond); |
| pthread_mutex_unlock(&len_mutex); |
| pthread_mutex_lock(&cond_array[num].mutex); |
| cond_array[num].state = 1; |
| COND_HEAD = addCondLinkNode(COND_HEAD,param->token, cond_array[num].index,cond_array[num].cond); |
| RLOGD("[Warren test] 开始等待 state = %d....\n",cond_array[num].state); |
| ret = pthread_cond_timedwait(&cond_array[num].cond,&cond_array[num].mutex,&outtime); |
| } |
| else |
| { |
| int w_status =0; |
| int waitTime = 10;//∑j=10*(2^1)+10*(2^2)+10*(2^3)+…+10*(2^n). |
| int count = 0; |
| do |
| { |
| if(count<7)//n=7,∑j=1270 |
| { |
| count++; |
| millli_sleep_with_restart(waitTime); |
| waitTime = waitTime*2; |
| } |
| else |
| { |
| w_status=1; |
| } |
| }while((cond_length>=CONDARRAYMAX)&&(w_status==0)); |
| |
| if(w_status==1) |
| { |
| RLOGD("wait cond link leisure failture!!! And callback timeout function\n"); |
| return; |
| /*call time out function |
| * |
| * |
| * |
| */ |
| } |
| pthread_mutex_lock(&len_mutex); |
| cond_length++; |
| pthread_mutex_unlock(&len_mutex); |
| COND_HEAD = addCondLinkNode(COND_HEAD,param->token, cond_array[num].index,cond_array[num].cond); |
| |
| taskWorking = 0; |
| pthread_cond_signal(&task_Cond); |
| |
| pthread_mutex_unlock(&len_mutex); |
| pthread_mutex_lock(&cond_array[num].mutex); |
| cond_array[num].state = 1; |
| COND_HEAD = addCondLinkNode(COND_HEAD,param->token, cond_array[num].index,cond_array[num].cond); |
| RLOGD("[Warren test] 开始等待 state = %d....\n",cond_array[num].state); |
| ret = pthread_cond_timedwait(&cond_array[num].cond,&cond_array[num].mutex,&outtime); |
| } |
| |
| } |
| cond_array[num].state = 0;//rest cond state. |
| cond_array[num].use_state = 0; |
| RLOGD("cond_array[%d] state=%d, use_state = %d",num,cond_array[num].state,cond_array[num].use_state); |
| pthread_mutex_unlock(&cond_array[num].mutex); |
| if(ret!=0) |
| { |
| //DeleteLinkNode(param->requestID); |
| COND_HEAD = DeleteLinkNode(param->token,COND_HEAD); |
| pthread_mutex_lock(&len_mutex); |
| cond_length--; |
| pthread_mutex_unlock(&len_mutex); |
| RLOGD("[Warren test] ret= %d,cond_index %d cond_length %d, token = %x,request %d is end\n",ret,param->cond_index,cond_length,param->token,param->requestID); |
| //some call back |
| // |
| // |
| return; |
| } |
| COND_HEAD = DeleteLinkNode(param->token,COND_HEAD); |
| pthread_mutex_lock(&len_mutex); |
| cond_length--; |
| pthread_mutex_unlock(&len_mutex); |
| RLOGD("[Warren test] ret= %d,cond_index %d cond_length %d, token = %x,request %d is end\n",ret,param->cond_index,cond_length,param->token,param->requestID); |
| free(param); |
| return; |
| } |
| int addTaskToTimerMan(int time,int32_t token,int request) |
| { |
| cond_used_state *node=NULL; |
| request_cond *requestCond=(request_cond*)malloc(sizeof(request_cond)); |
| if((requestCond==NULL) ||(timerArgv_t==NULL)) |
| { |
| return 1; |
| } |
| RLOGD("[Warren test] add token = %x, request %d\n",token,request); |
| node = findUnusedCond(timerArgv_t->cond_array,CONDARRAYMAX); |
| requestCond->cond_index=node->index; |
| requestCond->token=token; |
| requestCond->waitTime = time; |
| requestCond->requestID = request; |
| RLOGD("[Warren test] cond_index=%d,token = %x request %d\n",requestCond->cond_index,requestCond->token,request); |
| thpool_add_work(timerArgv_t->pool,startWaitResp,(void*)requestCond); |
| node->use_state = 1; |
| return 0; |
| |
| } |
| int sendSignalToTimer(int32_t token) |
| { |
| COND_NODE *node=NULL; |
| int cond_index = 0; |
| if(!(node = searchRequestinCondLink(token,COND_HEAD))) |
| { |
| //some thing will be do |
| return 1; |
| } |
| cond_index = node->cond_index; |
| RLOGD("[Warren test] 正在发送信号....\n"); |
| pthread_mutex_lock(&timerArgv_t->cond_array[cond_index].mutex); |
| pthread_cond_signal(&timerArgv_t->cond_array[cond_index].cond); |
| pthread_mutex_unlock(&timerArgv_t->cond_array[cond_index].mutex); |
| RLOGD("[Warren test] end cond_0....\n"); |
| return 0; |
| } |
| int initTimeManagement(int max_thread) |
| { |
| cond_used_state* node=NULL; |
| timerArgv_t=(timerArgv*)malloc(sizeof(timerArgv)); |
| if(timerArgv_t==NULL) |
| { |
| printf("timerArgv_t init fail!!!\n"); |
| exit(EXIT_FAILURE);; |
| } |
| initCondArray(); |
| timerArgv_t->cond_array=cond_array; |
| COND_HEAD = initConditionLink(); |
| if(!COND_HEAD) |
| { |
| printf("COND HEAD init fail!!!\n"); |
| exit(EXIT_FAILURE);; |
| } |
| puts("Making threadpool with 4 threads"); |
| threadpool thpool = thpool_init(max_thread); |
| timerArgv_t->pool = thpool; |
| return 0; |
| |
| } |