blob: 654b85df2cc43fef5ac022bcf97621615d29ee49 [file] [log] [blame]
/* ********************************
* 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;
}