⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwdlib.c

📁 将将基于VXWORKS的应用转换成LINUX的关键库源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * wdLib.c - defines the wrapper functions and data structures needed *           to implement a Wind River VxWorks (R) watchdog timer API  *           in a POSIX Threads environment. *   * Copyright (C) 2000, 2001  MontaVista Software Inc. * * Author : Gary S. Robertson * * VxWorks is a registered trademark of Wind River Systems, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Lesser General Public License for more details. ****************************************************************************/#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <semaphore.h>#include <sys/time.h>#include "v2pthread.h"#include "vxw_defs.h"#undef DIAG_PRINTFS/*******************************************************************************  Control block for v2pthread watchdog timer****  These watchdog timers provide a means of executing delayed or cyclic**  functions.  They are inherently 'one-shot' timers.  For cyclic operation,**  the timeout handler function must call wdStart to restart the timer.**  In the v2pthreads environment, these timers execute from the**  context of the system exception task rather tha the timer interrupt.*****************************************************************************/typedef struct v2pt_wdog{        /*        ** Mutex for watchdog access and modification        */    pthread_mutex_t        wdog_lock;        /*        ** Ticks remaining until timeout (zero if watchdog already expired).        */    int ticks_remaining;        /*        ** Function to be executed when ticks remaining decrements to zero.        */    void (*timeout_func)( int );        /*        ** Parameter to pass to timeout handler function.        */    int timeout_parm;        /*        ** Pointer to next watchdog control block in watchdog list.        */    struct v2pt_wdog *        nxt_wdog;} v2pt_wdog_t;/*******************************************************************************  External function and data references*****************************************************************************/extern void *   ts_malloc( size_t blksize );extern void   ts_free( void *blkaddr );extern void   taskLock( void );extern void   taskUnlock( void );extern v2pthread_cb_t *   tcb_for( int taskid );void *    task_wrapper( void *arg );/*******************************************************************************  v2pthread Global Data Structures*****************************************************************************//***  wdog_list is a linked list of watchdog control blocks.  It is used to locate**             watchdogs by their ID numbers.*/static v2pt_wdog_t *    wdog_list;/***  wdog_list_lock is a mutex used to serialize access to the watchdog list*/static pthread_mutex_t    wdog_list_lock = PTHREAD_MUTEX_INITIALIZER;/*******************************************************************************  wdog_valid - verifies whether the specified watchdog still exists, and if**                so, locks exclusive access to the watchdog for the caller.*****************************************************************************/static int   wdog_valid( v2pt_wdog_t *wdId ){        v2pt_wdog_t *current_wdog;    int found_wdog;    found_wdog = FALSE;    /*    **  Protect the watchdog list while we examine and modify it.    */    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&wdog_list_lock );    pthread_mutex_lock( &wdog_list_lock );    if ( wdog_list != (v2pt_wdog_t *)NULL )    {        /*        **  One or more watchdogs already exist in the watchdog list...        **  Scan the existing watchdogs for a matching ID.        */        for ( current_wdog = wdog_list;               current_wdog != (v2pt_wdog_t *)NULL;              current_wdog = current_wdog->nxt_wdog )        {#ifdef DIAG_PRINTFS             printf( "\r\nlooking for watchdog @ %p - found watchdog @ %p", wdId,                    current_wdog );#endif            if ( current_wdog == wdId )            {                /*                ** Lock mutex for watchdog access (it is assumed that a                ** 'pthread_cleanup_push()' has already been performed                **  by the caller in case of unexpected thread termination.)                */                pthread_mutex_lock( &(wdId->wdog_lock) );                found_wdog = TRUE;                break;            }        }    }     /*    **  Re-enable access to the watchdog list by other threads.    */    pthread_cleanup_pop( 1 );     return( found_wdog );}/******************************************************************************* link_wdog - appends a new watchdog control block pointer to the wdog_list*****************************************************************************/static void   link_wdog( v2pt_wdog_t *new_wdog ){    v2pt_wdog_t *current_wdog;    /*    **  Protect the watchdog list while we examine and modify it.    */    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&wdog_list_lock );    pthread_mutex_lock( &wdog_list_lock );    new_wdog->nxt_wdog = (v2pt_wdog_t *)NULL;    if ( wdog_list != (v2pt_wdog_t *)NULL )    {        /*        **  One or more watchdogs already exist in the watchdog list...        **  Insert the new entry at the tail of the list.        */        for ( current_wdog = wdog_list;               current_wdog->nxt_wdog != (v2pt_wdog_t *)NULL;              current_wdog = current_wdog->nxt_wdog );        current_wdog->nxt_wdog = new_wdog;#ifdef DIAG_PRINTFS         printf( "\r\nadd watchdog cb @ %p to list @ %p", new_wdog, current_wdog );#endif    }    else    {        /*        **  this is the first watchdog being added to the watchdog list.        */        wdog_list = new_wdog;#ifdef DIAG_PRINTFS         printf( "\r\nadd watchdog cb @ %p to list @ %p", new_wdog, &wdog_list );#endif    }     /*    **  Re-enable access to the watchdog list by other threads.    */    pthread_mutex_unlock( &wdog_list_lock );    pthread_cleanup_pop( 0 );}/******************************************************************************* unlink_wdog - removes a watchdog control block pointer from the wdog_list*****************************************************************************/static v2pt_wdog_t *   unlink_wdog( v2pt_wdog_t *wdId ){    v2pt_wdog_t *current_wdog;    v2pt_wdog_t *selected_wdog;    selected_wdog =  (v2pt_wdog_t *)NULL;    if ( wdog_list != (v2pt_wdog_t *)NULL )    {        /*        **  One or more watchdogs exist in the watchdog list...        **  Protect the watchdog list while we examine and modify it.        */        pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                              (void *)&wdog_list_lock );        pthread_mutex_lock( &wdog_list_lock );        /*        **  Scan the watchdog list for a wdog with a matching watchdog ID        */        if ( wdog_list == wdId )        {            /*            **  The first watchdog in the list matches the selected watchdog ID            */            selected_wdog = wdog_list;             wdog_list = selected_wdog->nxt_wdog;#ifdef DIAG_PRINTFS             printf( "\r\ndel watchdog cb @ %p from list @ %p", selected_wdog,                    &wdog_list );#endif        }        else        {            /*            **  Scan the next wdog for a matching wdId while retaining a            **  pointer to the current wdog.  If the next wdog matches,            **  select it and then unlink it from the watchdog list.            */            for ( current_wdog = wdog_list;                   current_wdog->nxt_wdog != (v2pt_wdog_t *)NULL;                  current_wdog = current_wdog->nxt_wdog )            {                if ( current_wdog->nxt_wdog == wdId )                {                    /*                    **  Queue ID of next wdog matches...                    **  Select the wdog and then unlink it by linking                    **  the selected wdog's next wdog into the current wdog.                    */                    selected_wdog = current_wdog->nxt_wdog;                    current_wdog->nxt_wdog = selected_wdog->nxt_wdog;#ifdef DIAG_PRINTFS                     printf( "\r\ndel watchdog cb @ %p from list @ %p",                            selected_wdog, current_wdog );#endif                    break;                }            }        }        /*        **  Re-enable access to the watchdog list by other threads.        */        pthread_mutex_unlock( &wdog_list_lock );        pthread_cleanup_pop( 0 );    }    return( selected_wdog );}/******************************************************************************* process_tick_for - performs service on the specified watchdog timer after**                    a system timer tick has elapsed.  Returns the address**                    of the next watchdog timer in the timer list, or NULL**                    if no further timers remain to  be processed*****************************************************************************/static v2pt_wdog_t *   process_tick_for( v2pt_wdog_t *wdId ){    v2pt_wdog_t *nxt_wdog;    /*    **  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 ) )    {        /*        **  Mark the next watchdog timer (if any) in the timer list.        */        nxt_wdog = wdId->nxt_wdog;#ifdef DIAG_PRINTFS         printf( "\r\ndecrement watchdog @ %p next watchdog @ %p", wdId,                nxt_wdog );#endif        /*        **  The timer is inactive if no ticks remaining        */#ifdef DIAG_PRINTFS         printf( "\r\nwatchdog @ %p has %d ticks remaining", wdId,                wdId->ticks_remaining );#endif        if ( wdId->ticks_remaining > 0 )        {            /*            **  Decrement ticks_remaining, and if this was the last tick,            **  check for a timeout handler function.            */            wdId->ticks_remaining--;             if ( (wdId->ticks_remaining == 0) &&                 (wdId->timeout_func != (void (*)( int ))NULL) )            {                /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -