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

📄 semlib.c

📁 如何将基于vxworks的应用程序移植到LINUX操作系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * semLib.c - defines the wrapper functions and data structures needed *            to implement a VxWorks semaphore API in a POSIX Threads *            environment. *   * Copyright (C) 2000  Monta Vista Software Inc. * * Author : Gary S. Robertson * * 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 "vxwk2pthread.h"#include "vxwkdefs.h"#undef DIAG_PRINTFS#define SEM_OPT_MASK       0x0f#define SEM_TYPE_MASK      0xf0#define BINARY_SEMA4       0x00#define MUTEX_SEMA4        0x10#define COUNTING_SEMA4     0x20#define SEND  0#define FLUSH 1#define KILLD 2/*******************************************************************************  Control block for VxWorks semaphore****  The basic POSIX semaphore does not provide for time-bounded waits nor**  for selection of a thread to ready based either on FIFO or PRIORITY-based**  waiting.  This 'wrapper' extends the POSIX pthreads semaphore to include**  the attributes of a VxWorks semaphore.*******************************************************************************/typedef struct vxwk_sema4{        /*        ** Option and Type Flags for semaphore        */    int         flags;        /*        ** Mutex and Condition variable for semaphore post/pend        */    pthread_mutex_t        sema4_lock;    pthread_cond_t        sema4_send;        /*        ** Mutex and Condition variable for semaphore delete        */    pthread_mutex_t        smdel_lock;    pthread_cond_t        smdel_cplt;        /*        **  Count of available 'tokens' for semaphore.        */    int        token_count;        /*        ** Type of send operation last performed on semaphore        */    int        send_type;        /*        **  Ownership nesting level for mutual exclusion semaphore.        */    int        recursion_level;        /*        ** Task control block ptr for task which currently owns semaphore        */    vxwk2pthread_cb_t *        current_owner;        /*        **  Pointer to next semaphore control block in semaphore list.        */    struct vxwk_sema4 *        nxt_sema4;        /*        ** First task control block in list of tasks waiting on semaphore        */    vxwk2pthread_cb_t *        first_susp;} vxwk_sema4_t;/*******************************************************************************  External function and data references*****************************************************************************/extern void *    ts_malloc( size_t blksize );extern void    ts_free( void *blkaddr );extern vxwk2pthread_cb_t *   my_tcb( void );extern void   taskLock( void );extern void   taskUnlock( void );extern STATUS   taskDelay( int interval );extern STATUS   taskSafe( void );extern STATUS   taskUnsafe( void );extern void   link_susp_tcb( vxwk2pthread_cb_t **list_head, vxwk2pthread_cb_t *new_entry );extern void   unlink_susp_tcb( vxwk2pthread_cb_t **list_head, vxwk2pthread_cb_t *entry );extern int   signal_for_my_task( vxwk2pthread_cb_t **list_head, int pend_order );/*******************************************************************************  VxWorks-to-pthread Global Data Structures*****************************************************************************//***  sema4_list is a linked list of semaphore control blocks.  It is used to**             validate semaphores by their ID numbers.*/static vxwk_sema4_t *    sema4_list;/***  sema4_list_lock is a mutex used to serialize access to the semaphore list*/static pthread_mutex_t    sema4_list_lock = PTHREAD_MUTEX_INITIALIZER;/*******************************************************************************  sema4_valid - verifies whether the specified semaphore still exists, and if**                so, locks exclusive access to the semaphore for the caller.*****************************************************************************/static int   sema4_valid( vxwk_sema4_t *sema4 ){        vxwk_sema4_t *current_smcb;    int found_sema4;    found_sema4 = FALSE;    /*    **  Protect the semaphore list while we examine and modify it.    */    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&sema4_list_lock );    pthread_mutex_lock( &sema4_list_lock );    if ( sema4_list != (vxwk_sema4_t *)NULL )    {        /*        **  One or more semaphores already exist in the semaphore list...        **  Scan the existing semaphores for a matching ID.        */        for ( current_smcb = sema4_list;               current_smcb != (vxwk_sema4_t *)NULL;              current_smcb = current_smcb->nxt_sema4 )        {            if ( current_smcb == sema4 )            {                /*                ** Lock mutex for semaphore 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( &(sema4->sema4_lock) );                found_sema4 = TRUE;                break;            }        }    }     /*    **  Re-enable access to the semaphore list by other threads.    */    pthread_mutex_unlock( &sema4_list_lock );    pthread_cleanup_pop( 0 );     return( found_sema4 );}/******************************************************************************* link_smcb - appends a new semaphore control block pointer to the sema4_list*****************************************************************************/static void   link_smcb( vxwk_sema4_t *new_sema4 ){    vxwk_sema4_t *current_smcb;    /*    **  Protect the semaphore list while we examine and modify it.    */    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&sema4_list_lock );    pthread_mutex_lock( &sema4_list_lock );    new_sema4->nxt_sema4 = (vxwk_sema4_t *)NULL;    if ( sema4_list != (vxwk_sema4_t *)NULL )    {        /*        **  One or more semaphores already exist in the semaphore list...        **  Insert the new entry at the tail of the list.        */        for ( current_smcb = sema4_list;               current_smcb->nxt_sema4 != (vxwk_sema4_t *)NULL;              current_smcb = current_smcb->nxt_sema4 );        current_smcb->nxt_sema4 = new_sema4;#ifdef DIAG_PRINTFS         printf( "\r\nadd semaphore cb @ %p to list @ %p", new_sema4,                current_smcb );#endif    }    else    {        /*        **  this is the first semaphore being added to the semaphore list.        */        sema4_list = new_sema4;#ifdef DIAG_PRINTFS         printf( "\r\nadd semaphore cb @ %p to list @ %p", new_sema4,                &sema4_list );#endif    }     /*    **  Re-enable access to the semaphore list by other threads.    */    pthread_mutex_unlock( &sema4_list_lock );    pthread_cleanup_pop( 0 );}/******************************************************************************* unlink_smcb - removes a semaphore control block pointer from the sema4_list*****************************************************************************/static vxwk_sema4_t *   unlink_smcb( vxwk_sema4_t *smid ){    vxwk_sema4_t *current_smcb;    vxwk_sema4_t *selected_smcb;    selected_smcb =  (vxwk_sema4_t *)NULL;    if ( sema4_list != (vxwk_sema4_t *)NULL )    {        /*        **  One or more semaphores exist in the semaphore list...        **  Protect the semaphore list while we examine and modify it.        */        pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                              (void *)&sema4_list_lock );        pthread_mutex_lock( &sema4_list_lock );        /*        **  Scan the semaphore list for an smcb with a matching semaphore ID        */        if ( sema4_list == smid )        {            /*            **  The first semaphore in the list matches the selected ID            */            selected_smcb = sema4_list;             sema4_list = selected_smcb->nxt_sema4;#ifdef DIAG_PRINTFS             printf( "\r\ndel semaphore cb @ %p from list @ %p", selected_smcb,                    &sema4_list );#endif        }        else        {            /*            **  Scan the next smcb for a matching smid while retaining a            **  pointer to the current smcb.  If the next smcb matches,            **  select it and then unlink it from the semaphore list.            */            for ( current_smcb = sema4_list;                   current_smcb->nxt_sema4 != (vxwk_sema4_t *)NULL;                  current_smcb = current_smcb->nxt_sema4 )            {                if ( current_smcb->nxt_sema4 == smid )                {                    /*                    **  Semaphore ID of next smcb matches...                    **  Select the smcb and then unlink it by linking                    **  the selected smcb's next smcb into the current smcb.                    */                    selected_smcb = current_smcb->nxt_sema4;                    current_smcb->nxt_sema4 = selected_smcb->nxt_sema4;#ifdef DIAG_PRINTFS                     printf( "\r\ndel semaphore cb @ %p from list @ %p",                            selected_smcb, current_smcb );#endif                    break;                }            }        }        /*        **  Re-enable access to the semaphore list by other threads.        */        pthread_mutex_unlock( &sema4_list_lock );        pthread_cleanup_pop( 0 );    }    return( selected_smcb );}/******************************************************************************* new_sema4 - creates a new VxWorks semaphore using pthreads resources*****************************************************************************/vxwk_sema4_t *    new_sema4( int count ){    vxwk_sema4_t *semaphore;    /*    **  First allocate memory for the semaphore control block    */    semaphore = (vxwk_sema4_t *)ts_malloc( sizeof( vxwk_sema4_t ) );    if ( semaphore != (vxwk_sema4_t *)NULL )    {        /*        **  Ok... got a control block.        **  Initialize the token count.        */        semaphore->token_count = count;        /*        ** Mutex and Condition variable for semaphore send/pend        */        pthread_mutex_init( &(semaphore->sema4_lock),                            (pthread_mutexattr_t *)NULL );        pthread_cond_init( &(semaphore->sema4_send),                           (pthread_condattr_t *)NULL );        /*        ** Mutex and Condition variable for semaphore delete/delete        */        pthread_mutex_init( &(semaphore->smdel_lock),                            (pthread_mutexattr_t *)NULL );        pthread_cond_init( &(semaphore->smdel_cplt),                           (pthread_condattr_t *)NULL );        /*        ** Type of send operation last performed on semaphore        */        semaphore->send_type = SEND;        /*        **  Ownership nesting level for mutual exclusion semaphore.        */        semaphore->recursion_level = 0;        /*        ** Task control block ptr for task which currently owns semaphore        */        semaphore->current_owner = (vxwk2pthread_cb_t *)NULL;        /*        ** First task control block in list of tasks waiting on semaphore        */        semaphore->first_susp = (vxwk2pthread_cb_t *)NULL;    }    return( semaphore );}/******************************************************************************* semBCreate - creates a VxWorks binary semaphore*****************************************************************************/vxwk_sema4_t *    semBCreate( int opt, int initial_state ){    vxwk_sema4_t *semaphore;    /*    **  First allocate memory for the semaphore control block    */    if ( initial_state == 0 )        semaphore = new_sema4( 0 );    else        semaphore = new_sema4( 1 );    if ( semaphore != (vxwk_sema4_t *)NULL )    {

⌨️ 快捷键说明

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