[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/ccapp/soft_timer.c b/ap/app/ccapp/soft_timer.c
new file mode 100644
index 0000000..5032f2f
--- /dev/null
+++ b/ap/app/ccapp/soft_timer.c
@@ -0,0 +1,493 @@
+/************************************************************************
+* °æÈ¨ËùÓÐ (C)2008, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º soft_timer.c
+* Îļþ±êʶ£º
+* ÄÚÈÝÕªÒª£º ¶¨ÒåͨÓõÄÈí¼þ¶¨Ê±Æ÷Ï߳̿â
+* ÆäËü˵Ã÷£º
+* µ±Ç°°æ±¾£º V1.0
+* ×÷ Õߣº Ö£ÓñæÃ
+* Íê³ÉÈÕÆÚ£º 2010-09-02
+*
+* Ð޸ļǼ1£º
+* ÐÞ¸ÄÈÕÆÚ£º2010-09-02
+* °æ ±¾ ºÅ£ºV1.0
+* ÐÞ ¸Ä ÈË£ºÖ£ÓñæÃ
+* ÐÞ¸ÄÄÚÈÝ£º³õʼ°æ±¾
+************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "soft_timer.h"
+
+/*
+#define SOFT_TIMER_DEBUG 1
+*/
+/********************************************
+ * Macro declaration
+ *******************************************/
+#define NEW_TIMER_STEP 10
+#define MAX_TIMER_POOL_NUM 33
+
+/********************************************
+ * static variables
+ *******************************************/
+static SOFT_TIMER g_timer_pool[MAX_TIMER_POOL_NUM] = {0};
+static SOFT_TIMER *g_pTimerHeader = NULL;
+static int g_timer_initialized = 0;
+
+pthread_mutex_t g_timer_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void* SoftTimer_Loop(void *args);
+
+/********************************************
+ * SoftTimer_Init
+ * initialize global variables
+ *******************************************/
+static int SoftTimer_Init(void)
+{
+ int result = 0;
+ pthread_attr_t attribute;
+ pthread_t stHandle;
+
+ if(0 == g_timer_initialized)
+ {
+ g_timer_initialized = 1;
+
+ pthread_attr_init(&attribute);
+ pthread_attr_setstacksize(&attribute, 32*1024);
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("Create soft timer first time, must create a thread now!\n");
+ #endif
+ result = pthread_create(&stHandle, &attribute, SoftTimer_Loop, NULL);
+ if(0 != result)
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("StartSoftTimer failed, create thread fail %d!\n", result);
+ #endif
+ return ERROR;
+ }
+
+ g_pTimerHeader = &g_timer_pool[0];
+ g_pTimerHeader->next = g_pTimerHeader;
+ g_pTimerHeader->prev = g_pTimerHeader;
+ g_pTimerHeader->used = 1;
+ }
+
+ return OK;
+}
+
+/********************************************
+ * SetBasicTimerEx
+ * call [setitimer] to set basic timer
+ *******************************************/
+static void SetBasicTimerEx(int value)
+{
+ struct itimerval stTimer = {0};
+ struct itimerval oldTimer = {0};
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SetBasicTimerEx: value=%d\n", value);
+ #endif
+
+ stTimer.it_value.tv_sec = value / 1000;
+ stTimer.it_value.tv_usec = (value * 1000) % 1000000;
+
+ //stTimer.it_interval.tv_sec = stTimer.it_value.tv_sec;
+ //stTimer.it_interval.tv_usec = stTimer.it_value.tv_usec;
+
+ setitimer(ITIMER_REAL, &stTimer, &oldTimer);
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SetBasicTimerEx: tv_sec=%d, tv_usec=%d\n", stTimer.it_value.tv_sec, stTimer.it_value.tv_usec);
+ printf("SetBasicTimerEx:oldTimer tv_sec=%d, tv_usec=%d\n", oldTimer.it_value.tv_sec, oldTimer.it_value.tv_usec);
+ #endif
+}
+
+/********************************************
+ * SoftTimer_Add
+ * add a soft timer to double linked list
+ *******************************************/
+static int SoftTimer_Add(SOFT_TIMER *pHeader, SOFT_TIMER *pItem)
+{
+ SOFT_TIMER *pTmp = pHeader;
+
+ if(NULL == pHeader || NULL == pItem)
+ {
+ return -1;
+ }
+
+ do
+ {
+ if(pTmp->timerValue <= pItem->timerValue)
+ {
+ pTmp = pTmp->next;
+ }
+ else
+ {
+ break;
+ }
+ } while(pTmp != pHeader);
+
+ if(pTmp != pHeader)
+ {
+ pItem->next = pTmp;
+ pItem->prev = pTmp->prev;
+ pTmp->prev->next = pItem;
+ pTmp->prev = pItem;
+ }
+ else
+ {
+ pItem->next = pTmp;
+ pItem->prev = pTmp->prev;
+ pTmp->prev->next = pItem;
+ pTmp->prev = pItem;
+ }
+
+ return 0;
+}
+
+/********************************************
+ * SoftTimer_Delete
+ * delete a soft timer from double linked list
+ *******************************************/
+static int SoftTimer_Delete(SOFT_TIMER *pHeader, SOFT_TIMER *pItem)
+{
+ if(NULL == pHeader || NULL == pItem)
+ {
+ return -1;
+ }
+
+ if(pItem == pHeader)
+ {
+ return 0;
+ }
+
+ pItem->prev->next = pItem->next;
+ pItem->next->prev = pItem->prev;
+
+ return 0;
+}
+
+/********************************************
+ * SoftTimer_GetSize
+ * get total size of double linked list
+ *******************************************/
+static int SoftTimer_GetSize(SOFT_TIMER *pHeader)
+{
+ int size = 0;
+ SOFT_TIMER *pTmp = pHeader->next;
+
+ while(pTmp != pHeader)
+ {
+ size++;
+ pTmp = pTmp->next;
+ }
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SoftTimer_GetSize: size=%d\n", size);
+ #endif
+ return size;
+}
+
+/********************************************
+ * SoftTimer_Adjust
+ * adjust soft-timer's value in the double linked list
+ *******************************************/
+static int SoftTimer_AdjustTimerValue(SOFT_TIMER *pHeader, int value)
+{
+ SOFT_TIMER *pTmp = pHeader->next;
+
+ while(pTmp != pHeader)
+ {
+ pTmp->timerValue -= value;
+ pTmp = pTmp->next;
+ }
+ return 0;
+}
+
+/********************************************
+ * SoftTimer_Handler
+ * handler of soft-timer
+ *******************************************/
+static void SoftTimer_Handler(void)
+{
+ int index;
+ SOFT_TIMER *pHeader = g_pTimerHeader;
+ SOFT_TIMER *pTmp = pHeader->next;
+ unsigned int curTime = 0;
+
+ curTime = (pTmp != pHeader?pTmp->timerValue:0);
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SoftTimer_Ops: curTime=%d\n", curTime);
+ #endif
+
+ pthread_mutex_lock(&g_timer_mutex);
+
+ while(pTmp != pHeader)
+ {
+ pTmp->timerValue -= curTime;
+ if(pTmp->timerValue <= 0)
+ {
+ pTmp->procCallBack(pTmp->args);
+
+ if(TIMER_FLAG_RESTART == pTmp->ucFlag)
+ {
+ pTmp->timerValue = pTmp->ulNextInterval;
+ }
+ else
+ {
+ pTmp->timerValue = -1;
+ }
+ pTmp->done = 1;
+ }
+ pTmp = pTmp->next;
+ }
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SoftTimer_Ops:[1] %d\n", SoftTimer_GetSize(pHeader));
+ #endif
+
+ for(index = 1; index < MAX_TIMER_POOL_NUM; index++)
+ {
+ if(g_timer_pool[index].used && g_timer_pool[index].done)
+ {
+ g_timer_pool[index].done = 0;
+
+ SoftTimer_Delete(pHeader, &g_timer_pool[index]);
+
+ if(g_timer_pool[index].timerValue > 0)
+ {
+ SoftTimer_Add(pHeader, &g_timer_pool[index]);
+ }
+ else
+ {
+ memset(&g_timer_pool[index], 0, sizeof(SOFT_TIMER));
+ }
+ }
+ }
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SoftTimer_Ops:[2] %d\n", SoftTimer_GetSize(pHeader));
+ #endif
+
+ SetBasicTimerEx(pHeader->next->timerValue);
+
+ pthread_mutex_unlock(&g_timer_mutex);
+
+ #ifdef SOFT_TIMER_DEBUG
+ printf("SoftTimer_Ops: nextTime=%d\n", pHeader->next->timerValue);
+ #endif
+
+ return;
+}
+
+/********************************************
+ * SoftTimer_Loop
+ * A thread entry for soft-timer!
+ *******************************************/
+static void* SoftTimer_Loop(void *args)
+{
+ struct sigaction act;
+
+ act.sa_handler =(void*) SoftTimer_Handler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGALRM, &act, NULL);
+
+ while(1)
+ {
+ pause();
+ }
+}
+
+static void SoftTimer_Process(int freeIndex)
+{
+ ULONG ulResidue = 0;
+ ULONG ulQuotient = 0;
+ int oldTimeValue = 0;
+ int leftTimeValue = 0;
+
+ struct itimerval stTimer = {0};
+
+ if(0 == SoftTimer_GetSize(g_pTimerHeader))
+ {
+ SoftTimer_Add(g_pTimerHeader, &( g_timer_pool[freeIndex]));
+ SetBasicTimerEx(g_pTimerHeader->next->timerValue);
+ }
+ else
+ {
+ oldTimeValue = g_pTimerHeader->next->timerValue;
+ if(oldTimeValue > 0)
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("CreateSoftTimer: oldTimeValue=%d\n", oldTimeValue);
+ #endif
+ getitimer(ITIMER_REAL, &stTimer);
+ #ifdef SOFT_TIMER_DEBUG
+ printf("CreateSoftTimer: tv_sec=%d, tv_usec=%d\n", stTimer.it_value.tv_sec, stTimer.it_value.tv_usec);
+ #endif
+ leftTimeValue = stTimer.it_value.tv_sec * 1000 + (stTimer.it_value.tv_usec/1000);
+
+ ulResidue = leftTimeValue % NEW_TIMER_STEP;
+ if (0 != ulResidue)
+ {
+ ulQuotient = leftTimeValue / NEW_TIMER_STEP;
+ leftTimeValue = (ulQuotient + 1) * NEW_TIMER_STEP;
+ }
+ #ifdef SOFT_TIMER_DEBUG
+ printf("CreateSoftTimer: oldTimeValue=%d, leftTimeValue=%d\n", oldTimeValue, leftTimeValue);
+ #endif
+ if(oldTimeValue - leftTimeValue >= NEW_TIMER_STEP)
+ {
+ SoftTimer_AdjustTimerValue(g_pTimerHeader, oldTimeValue - leftTimeValue);
+ }
+
+ SoftTimer_Add(g_pTimerHeader, &( g_timer_pool[freeIndex]));
+ SetBasicTimerEx(g_pTimerHeader->next->timerValue);
+ }
+ }
+}
+
+/********************************************
+ * CreateSoftTimer
+ * create a new soft-timer!
+ *******************************************/
+LONG CreateSoftTimer(USHORT usTimerID,
+ UCHAR ucFlag,
+ ULONG ulInterval,
+ void * (*procCallBack)(void *),
+ void *args)
+{
+ int ucIndex = 0;
+ int freeIndex = 0;
+
+ ULONG ulResidue = 0;
+ ULONG ulQuotient = 0;
+
+ if (NULL == procCallBack)
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("CreateSoftTimer failed, procCallBack is NULL!\n");
+ #endif
+ return ERROR;
+ }
+
+ pthread_mutex_lock(&g_timer_mutex);
+
+ if(OK != SoftTimer_Init())
+ {
+ pthread_mutex_unlock(&g_timer_mutex);
+ return ERROR;
+ }
+
+ for(ucIndex = 1, freeIndex = 0; ucIndex < MAX_TIMER_POOL_NUM; ucIndex++)
+ {
+ /*same timer id exist, warning, return error*/
+ if (g_timer_pool[ucIndex].used && (usTimerID == g_timer_pool[ucIndex].usTimerID))
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("Same timer id 0x%04x exist!\n", usTimerID);
+ #endif
+ pthread_mutex_unlock(&g_timer_mutex);
+ return ERROR;
+ }
+ if ((0 == g_timer_pool[ucIndex].used) && (0 == freeIndex))
+ {
+ freeIndex = ucIndex;
+ }
+ }
+
+ /* No empty timer left */
+ if (0 == freeIndex)
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("StartSoftTimer 0x%04x failed, queue full!\n", usTimerID);
+ #endif
+ pthread_mutex_unlock(&g_timer_mutex);
+ return ERROR;
+ }
+
+ /* Adjust interval value, it must multiple of 10 */
+ ulResidue = ulInterval % NEW_TIMER_STEP;
+ if (0 != ulResidue)
+ {
+ ulQuotient = ulInterval / NEW_TIMER_STEP;
+ ulInterval = (ulQuotient + 1) * NEW_TIMER_STEP;
+ }
+
+ g_timer_pool[freeIndex].used = 1;
+ g_timer_pool[freeIndex].usTimerID = usTimerID;
+ g_timer_pool[freeIndex].ucFlag = ucFlag;
+ g_timer_pool[freeIndex].ulCurInterval = ulInterval;
+ g_timer_pool[freeIndex].ulNextInterval = ulInterval;
+ g_timer_pool[freeIndex].procCallBack = procCallBack;
+ g_timer_pool[freeIndex].args = args;
+ g_timer_pool[freeIndex].timerValue = ulInterval;
+
+ SoftTimer_Process(freeIndex);
+ #ifdef SOFT_TIMER_DEBUG
+ printf("CreateSoftTimer index %d success: \n"
+ "usTimerID = %d, \n"
+ "ucFlag = %d, \n"
+ "ulCurInterval = %ld, \n"
+ "ulNextInterval = %ld, \n"
+ "procCallBack = %p, \n"
+ "args = %p. \n",
+ freeIndex,
+ usTimerID,
+ ucFlag,
+ ulInterval,
+ ulInterval,
+ procCallBack,
+ args);
+ #endif
+ pthread_mutex_unlock(&g_timer_mutex);
+
+ return OK;
+}
+
+/********************************************
+ * DeleteSoftTimer
+ * delete a soft-timer!
+ *******************************************/
+LONG DeleteSoftTimer(USHORT usTimerID)
+{
+ UCHAR ucIndex = 0;
+
+ pthread_mutex_lock(&g_timer_mutex);
+
+ for(ucIndex = 1; ucIndex < MAX_TIMER_POOL_NUM; ucIndex++)
+ {
+ if(g_timer_pool[ucIndex].used && (usTimerID == g_timer_pool[ucIndex].usTimerID))
+ {
+ break;
+ }
+ }
+
+ if (ucIndex >= MAX_TIMER_POOL_NUM)
+ {
+ #ifdef SOFT_TIMER_DEBUG
+ printf("DeleteSoftTimer 0x%04x failed, not exist!\n", usTimerID);
+ #endif
+ pthread_mutex_unlock(&g_timer_mutex);
+ return ERROR;
+ }
+
+ SoftTimer_Delete(g_pTimerHeader, &( g_timer_pool[ucIndex]));
+ memset(&g_timer_pool[ucIndex], 0, sizeof(SOFT_TIMER));
+ #ifdef SOFT_TIMER_DEBUG
+ printf("DeleteSoftTimer 0x%04x success!\n", usTimerID);
+ #endif
+ pthread_mutex_unlock(&g_timer_mutex);
+ return OK;
+}