📄 lwdlib.c
字号:
** Unlock the queue mutex so the timeout handler can call ** wdStart if desired. This would create a race condition, ** but (1) the task executing this function cannot be ** preempted at this point by other v2pthread tasks, and ** (2) the timer list itself is locked at this point. */ pthread_mutex_unlock( &(wdId->wdog_lock) );#ifdef DIAG_PRINTFS printf( "\r\nwatchdog @ %p calling function @ %p", wdId, wdId->timeout_func );#endif /* ** Execute the timeout handler, passing it the ** timer handler parameter. */ (*(wdId->timeout_func))( wdId->timeout_parm ); } else /* ** Unlock the queue mutex. */ pthread_mutex_unlock( &(wdId->wdog_lock) ); } else { /* ** Unlock the queue mutex. */ pthread_mutex_unlock( &(wdId->wdog_lock) ); } } else { /* ** Invalid watchdog timer specified - return NULL */ nxt_wdog = (v2pt_wdog_t *)NULL;#ifdef DIAG_PRINTFS printf( "\r\nwatchdog @ %p invalid... next watchdog @ %p", wdId, nxt_wdog );#endif } /* ** Clean up the opening pthread_cleanup_push() */ pthread_cleanup_pop( 0 ); return( nxt_wdog );}/******************************************************************************* process_timer_list - performs service on all active watchdog timers after** a system timer tick has elapsed.*****************************************************************************/void process_timer_list( void ){ v2pt_wdog_t *nxt_wdog; if ( wdog_list != (v2pt_wdog_t *)NULL ) { /* ** One or more watchdogs exist in the watchdog list... ** Now traverse the watchdog timer list, servicing all active timers. */ for ( nxt_wdog = wdog_list; nxt_wdog != (v2pt_wdog_t *)NULL; ) {#ifdef DIAG_PRINTFS printf( "\r\nprocess next watchdog @ %p", nxt_wdog );#endif nxt_wdog = process_tick_for( nxt_wdog ); } }}/******************************************************************************* wdCancel - De-activates an existing watchdog timer, but does not remove it** from the timer list. The same watchdog may be re-started or** re-used for other timer purposes.*****************************************************************************/STATUS wdCancel( v2pt_wdog_t *wdId ){ STATUS error; error = OK; /* ** First ensure that the specified watchdog exists and that we have ** exclusive access to it. */ pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&(wdId->wdog_lock)); if ( wdog_valid( wdId ) ) { /* ** Zero the ticks remaining without executing the timeout function. */ wdId->ticks_remaining = 0; /* ** Unlock the queue mutex. */ pthread_mutex_unlock( &(wdId->wdog_lock) ); } else { error = S_objLib_OBJ_ID_ERROR; } /* ** Clean up the opening pthread_cleanup_push() */ pthread_cleanup_pop( 0 ); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* wdCreate - Creates a new (inactive) watchdog timer.*****************************************************************************/v2pt_wdog_t * wdCreate( void ){ v2pt_wdog_t *new_wdog; /* ** Allocate memory for the watchdog timer control block. */ new_wdog = (v2pt_wdog_t *)ts_malloc( sizeof( v2pt_wdog_t ) ); if ( new_wdog != (v2pt_wdog_t *)NULL ) { /* ** Init mutex for watchdog access and modification. */ pthread_mutex_init( &(new_wdog->wdog_lock), (pthread_mutexattr_t *)NULL ); /* ** Zero ticks remaining until timeout so watchdog is inactive. */ new_wdog->ticks_remaining = 0; /* ** Link the new watchdog control block into the watchdog timer list. */ link_wdog( new_wdog ); } return( new_wdog );}/******************************************************************************* wdDelete - Removes te specified watchdog timer from the watchdog list** and deallocates the memory used by the watchdog.*****************************************************************************/STATUS wdDelete( v2pt_wdog_t *wdId ){ STATUS error; error = OK; /* ** First ensure that the specified watchdog exists and that we have ** exclusive access to it. */ pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&(wdId->wdog_lock)); if ( wdog_valid( wdId ) ) { /* ** First remove the watchdog from the watchdog list */ unlink_wdog( wdId ); /* ** Finally delete the watchdog control block itself; */ ts_free( (void *)wdId ); /* ** Unlock the queue mutex. */ pthread_mutex_unlock( &(wdId->wdog_lock) ); } else { error = S_objLib_OBJ_ID_ERROR; } /* ** Clean up the opening pthread_cleanup_push() */ pthread_cleanup_pop( 0 ); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* wdStart - Activates or reactivates an existing watchdog timer.*****************************************************************************/STATUS wdStart( v2pt_wdog_t *wdId, int delay, void (*funcptr)( int ), int parm ){ STATUS error; error = OK; /* ** First ensure that the specified watchdog exists and that we have ** exclusive access to it. */ pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&(wdId->wdog_lock)); if ( wdog_valid( wdId ) ) { /* ** Ticks remaining until timeout (zero if watchdog already expired). ** (On an x86 Linux system, the minimum taskDelay appears to be ** 20 msec - not 10 msec. */ wdId->ticks_remaining = delay / 2; if ( wdId->ticks_remaining < 1 ) wdId->ticks_remaining = 1; /* ** Function to be executed when ticks remaining decrements to zero. */ wdId->timeout_func = funcptr; /* ** Parameter to pass to timeout handler function. */ wdId->timeout_parm = parm; /* ** Unlock the queue mutex. */ pthread_mutex_unlock( &(wdId->wdog_lock) ); } else { error = S_objLib_OBJ_ID_ERROR; } /* ** Clean up the opening pthread_cleanup_push() */ pthread_cleanup_pop( 0 ); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* self_starter - called from a task-restart watchdog timer. Starts a new** pthread for the specified task and deletes the watchdog.*****************************************************************************/static v2pt_wdog_t *restart_wdog;static void self_starter( int taskid ){ v2pthread_cb_t *tcb; /* ** Delete the task restart watchdog regardless of the success or failure ** of the restart operation. */ wdDelete( restart_wdog ); /* ** Get the address of the task control block for the specified task ID. */ tcb = tcb_for( taskid ); if ( tcb != (v2pthread_cb_t *)NULL ) { /* ** Mark the task as ready to run and create a new pthread using the ** attributes and entry point defined in the task control block. */ tcb->state = READY; tcb->pthrid = (pthread_t)NULL; pthread_create( &(tcb->pthrid), &(tcb->attr), task_wrapper, (void *)tcb ); }}/******************************************************************************* selfRestart - restarts the specified (existing) v2pthread task after said** task has terminated itself.*****************************************************************************/void selfRestart( v2pthread_cb_t *restart_tcb ){ /* ** First create a watchdog timer to handle the restart operation. */ restart_wdog = wdCreate(); if ( restart_wdog != (v2pt_wdog_t *)NULL ) { /* ** Start the watchdog timer to expire after one tick and to call ** a function which will first restart the specified task and ** then delete the restart watchdog timer. */ wdStart( restart_wdog, 1, self_starter, restart_tcb->taskid ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -