ClRcT createAsyncSendTimer(ClRmdAsyncRecordT *pAsyncRecord,
                           void           *pTimerData)
{
    ClTimerTimeOutT timerExpiry;
    ClRcT retCode = CL_OK;
    ClInt32T timeout = pAsyncRecord->timeout;

    CL_FUNC_ENTER();

    if (timeout == 0)
        timeout = CL_RMD_TIMEOUT_FOREVER;

    if(timeout != CL_RMD_TIMEOUT_FOREVER && pAsyncRecord->noOfRetry > 0)
    {
        timeout *= pAsyncRecord->noOfRetry;
    }

    timerExpiry.tsSec = (timeout / 1000);
    timerExpiry.tsMilliSec = (timeout % 1000);
    retCode =
        clTimerCreate(timerExpiry, CL_TIMER_REPETITIVE,
                      CL_TIMER_SEPARATE_CONTEXT, rmdSendTimerFunc,
                      pTimerData, &pAsyncRecord->timerID);
    CL_FUNC_EXIT();
    return retCode;


}
ClRcT clComponentTimerInit(ClEoExecutionObjT* peoObj)
{
    ClRcT    rc = CL_OK;
    ClTimerTimeOutT     ComponentTimeOut = {0,0};
    

    ComponentTimeOut.tsSec = 0;
    ComponentTimeOut.tsMilliSec = COMPONENT_CALLBACK_TIME;
    
    rc= clTimerCreate(ComponentTimeOut,
                      CL_TIMER_ONE_SHOT,
                      CL_TIMER_SEPARATE_CONTEXT,
                      clComponentCallBack,
                      (void*)peoObj,
                      &gComponentTimerHandle);

    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, (" clTimerCreate failed with rc: 0x%x \n", rc));
        return rc;
    }

    rc = clTimerStart(gComponentTimerHandle);
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, (" clTimerStart failed with rc: 0x%x \n", rc));
        return rc;
    }

    return rc;
}
/*******************************************************************************
API: alarmClockInitialze

Description : Set the alarm clock to all zeroes, and the boolean variable to 
              indicate non-running clock

Arguments In: 
    none
Arguments Out:
    none
Return Value:
    none
*******************************************************************************/
ClRcT alarmClockInitialize ( void )
{
    ClRcT                rc = CL_OK;
    ClTimerTimeOutT      timeOut;

    alarmClock.clockTime.hour   = 0;
    alarmClock.clockTime.minute = 0;
    alarmClock.clockTime.second = 0;

    alarmClock.alarm.time.hour   = 0;
    alarmClock.alarm.time.minute = 0;
    alarmClock.alarm.time.second = 0;
    alarmClock.alarm.reaction    = ALARM_REACTION_NONE;

    alarmClock.clockId          = 0;;

    alarmClock.clockRunning = CL_FALSE;
    alarmClock.alarmSet     = CL_FALSE;

    /* one second in the clock is 50 millisecond of real time
     * as an enhancement this can be made provisionable as well
     */
    timeOut.tsSec = 1;
    timeOut.tsMilliSec = 0;

/*
    rc = clTimerInitialize(NULL);
    if (rc != CL_OK)
    {
        alarmClockLogWrite(CL_LOG_SEV_CRITICAL,
                    "alarmClockInitialize(pid=%d): Timer initialize failed:0x%x\n", 
                    getpid(), rc);
        return rc;
    }
*/

    rc = clTimerCreate(timeOut, CL_TIMER_REPETITIVE, CL_TIMER_SEPARATE_CONTEXT,
                       (ClTimerCallBackT)&alarmClockAdvance, NULL, &timerHandle);
    if (rc != CL_OK)
    {
        alarmClockLogWrite(CL_LOG_SEV_CRITICAL,
                    "alarmClockInitialize(pid=%d): Timer start failed: 0x%x\n", 
                    getpid(), rc);
    }

    alarmClockLogWrite(CL_LOG_DEBUG,
            "alarmClockInitialize(pid=%d): Clock Initialize successful\n", 
            getpid());

    return rc;
}
ClRcT
clTimerCreateAndStart (ClTimerTimeOutT      timeOut,        /* the timeout, in clockticks */
                       ClTimerTypeT    type,           /* one shot or repetitive */
                       ClTimerContextT timerTaskSpawn, /* whether to spawn off the timer function
                                                 * as a separate task or invoke it in the
                                                 * same context as the timer-task
                                                 */
                       ClTimerCallBackT     fpAction,       /* the function to be called on timeout */
                       void*            actionArgument, /* the argument to the function called on timeout */
                       ClTimerHandleT* pTimerHandle)
{
    ClRcT returnCode = 0;

    CL_FUNC_ENTER();
    returnCode = clTimerCreate (timeOut,
                                type,
                                timerTaskSpawn,
                                fpAction,
                                actionArgument,
                                pTimerHandle);

    if (returnCode != CL_OK) {
        CL_FUNC_EXIT();
        return (returnCode);
    }

    returnCode = clTimerStart (*pTimerHandle);

    if (returnCode != CL_OK) {
        CL_FUNC_EXIT();
        return (returnCode);
    }

    CL_FUNC_EXIT();
    return (CL_OK);
}
ClRcT 
clFaultHistoryInit(ClUint32T binNumbers){

   ClRcT          rc = CL_OK;
   ClTimerTimeOutT      timeOut;


   /* fault history containers can be accessed by FM thread, timer thread
    * etc .. So before accessing the containers, the threads shd take the
    * mutex
    */
    rc = clOsalMutexCreateAndLock(&shfaultHistoryMutex);
    if (rc != CL_OK)
    {
        clLogWrite(CL_LOG_HANDLE_APP, 
               CL_LOG_ERROR,   
               CL_FAULT_SERVER_LIB,
               CL_FAULT_LOG_1_MUTEX,
               "Fault History data base");
      return CL_FAULT_ERR_HISTORY_MUTEX_CREATE_ERROR;
    }

   /* 
    * Create a circular queue with number of nodes = binNumbers
    * Each node is a linked list of fault recovery/history record 
       sorted by key composed of category and severity
    */
   /*
    * Create a repetitive timer at frequency interval = binInterval
    */

   rc = clClistCreate( MAX_FAULT_BUCKETS,
                          CL_DROP_FIRST,
                           (ClClistDeleteCallbackT) clFaultHis2MinBucketDelete,
                           (ClClistDeleteCallbackT) clFaultHis2MinBucketDelete,
                           &sfaultHistoryList);

   if (rc != CL_OK ) 
   {
      clLogError("FLT", NULL, "Error in creating Clist, rc [0x%x]", 
              rc);
      goto unlock_exit;
   }


   /* start a 2 minute timer */
    timeOut.tsSec = binNumbers;
    timeOut.tsMilliSec = 0; 

    if ((rc = clTimerCreate(timeOut,
                              CL_TIMER_REPETITIVE,
                              CL_TIMER_SEPARATE_CONTEXT, 
                              (ClTimerCallBackT) clFault2MinHistoryCallback,
                              NULL, 
                              &sFaultMan2MinHistoryTimerH)
                            ) != CL_OK)
   {
     clLogError("FLT", NULL, "Failed to create repetitive timer for \
                            fault manager's 2 min history");
      goto unlock_exit;
    }