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

📄 ltasklib.c

📁 将将基于VXWORKS的应用转换成LINUX的关键库源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        current_tcb = tcb_for( tid );    /*    **  Make sure valid TCB found in scan of task list    */    if ( current_tcb != (v2pthread_cb_t *)NULL )    {        /*        **  Found the task being deleted... first ensure that we        **  awaken any other tasks pended on deletion of this task        */        if ( current_tcb->first_susp != (v2pthread_cb_t *)NULL )        {            notify_task_delete( current_tcb );        }        /*        **  Any tasks pended on deletion of this task have been awakened.        **  Proceed with task deletion.        */#ifdef DIAG_PRINTFS         printf( "\r\ntaskDeleteForce - delete pthread for task @ tcb %p",                current_tcb );        fflush( stdout );#endif        if ( current_tcb != self_tcb )        {            /*            **  Task being deleted is not the current task.            **  Kill the task pthread and wait for it to die.            **  Then de-allocate its data structures.            */#ifdef DIAG_PRINTFS             printf( "\r\ntaskDeleteForce - other tcb @ %p", current_tcb );            fflush( stdout );#endif            pthread_cancel( current_tcb->pthrid );            pthread_join( current_tcb->pthrid, (void **)NULL );            tcb_delete( current_tcb );        }        else        {            /*            **  Kill the currently executing task's pthread            **  and then de-allocate its data structures.            */#ifdef DIAG_PRINTFS             printf( "\r\ntaskDeleteForce - self tcb @ %p", current_tcb );            fflush( stdout );#endif            pthread_detach( self_tcb->pthrid );            pthread_cleanup_push( (void(*)(void *))tcb_delete,                                  (void *)self_tcb );            pthread_exit( (void *)NULL );            pthread_cleanup_pop( 0 );        }    }    else        /*        **  No TCB found in task list for specified tid... must have already        **  been deleted.        */        error = S_objLib_OBJ_DELETED;    taskUnlock();    if ( error != OK )    {        errno = (int)error;        error = ERROR;    }    return( error );}/*******************************************************************************  cleanup_scheduler_lock ensures that a killed pthread releases the**                         scheduler lock if it owned it.*****************************************************************************/static void     cleanup_scheduler_lock( void *tcb ){    v2pthread_cb_t *mytcb;    mytcb = (v2pthread_cb_t *)tcb;    pthread_mutex_lock( &v2pthread_task_lock );    if ( scheduler_locked == pthread_self() )    {        taskLock_level = 0;        scheduler_locked = (pthread_t)NULL;    }    pthread_mutex_unlock( &v2pthread_task_lock );}/*******************************************************************************  task_wrapper is a pthread used to 'contain' a v2pthread task.*****************************************************************************/void *    task_wrapper( void *arg ){    v2pthread_cb_t *tcb;    /*    **  Ensure that errno for this thread is cleared.    */    errno = 0;        /*    **  Make a parameter block pointer from the caller's argument    **  Then extract the needed info from the parameter block and    **  free its memory before beginning the v2pthread task    */    tcb = (v2pthread_cb_t *)arg;    /*    **  Ensure that this pthread will release the scheduler lock if killed.    */    pthread_cleanup_push( cleanup_scheduler_lock, (void *)tcb );    /*    **  Call the v2pthread task.  Normally this is an endless loop and doesn't    **  return here.    */#ifdef DIAG_PRINTFS     printf( "\r\ntask_wrapper starting task @ %p tcb @ %p:",            tcb->entry_point, tcb );    sleep( 1 );#endif    (*(tcb->entry_point))( tcb->parms[0], tcb->parms[1], tcb->parms[2],                           tcb->parms[3], tcb->parms[4], tcb->parms[5],                           tcb->parms[6], tcb->parms[7], tcb->parms[8],                           tcb->parms[9] );    /*    **  If for some reason the task above DOES return, clean up the    **  pthread and task resources and kill the pthread.    */    pthread_cleanup_pop( 1 );    /*    **  NOTE taskDelete takes no action if the task has already been deleted.    */    taskDeleteForce( tcb->taskid );    return( (void *)NULL );}/******************************************************************************* taskDelay - suspends the calling task for the specified number of ticks.**            ( one tick is currently implemented as ten milliseconds )*****************************************************************************/STATUS   taskDelay( int interval ){    struct timeval now, timeout;    unsigned long usec;    v2pthread_cb_t *tcb;    /*    **  Calculate timeout delay in seconds and microseconds    */    usec = (unsigned long)(interval * V2PT_TICK * 1000);    /*    **  Update the task state.    */    tcb = my_tcb();    tcb->state |= DELAY;    /*    **  Delay of zero means yield CPU to other tasks of same priority    */    if ( usec > 0L )    {        /*        **  Establish absolute time at expiration of delay interval        */        gettimeofday( &now, (struct timezone *)NULL );        timeout.tv_sec = now.tv_sec;        timeout.tv_usec = now.tv_usec;        timeout.tv_usec += usec;        if ( timeout.tv_usec > 1000000 )        {            timeout.tv_sec += timeout.tv_usec / 1000000;            timeout.tv_usec = timeout.tv_usec % 1000000;        }        /*        **  Wait for the current time of day to reach the time of day calculated        **  after the timeout expires.  The loop is necessary since the thread        **  may be awakened by signals before the timeout has elapsed.        */        while ( usec > 0 )        {            /*            **  Add a cancellation point to this loop,            **  since there are no others.            */            pthread_testcancel();            usleep( usec );            gettimeofday( &now, (struct timezone *)NULL );            if ( timeout.tv_usec > now.tv_usec )            {                usec = timeout.tv_usec - now.tv_usec;                if ( timeout.tv_sec < now.tv_sec )                    usec = 0;                else                    usec += ((timeout.tv_sec - now.tv_sec) * 1000000);            }            else            {                usec = (timeout.tv_usec + 1000000) - now.tv_usec;                if ( (timeout.tv_sec - 1) < now.tv_sec )                    usec = 0;                else                    usec += (((timeout.tv_sec - 1) - now.tv_sec) * 1000000);            }        }    }    else        /*        **  Yield to any other task of same priority without blocking.        */        sched_yield();    /*    **  Update the task state.    */    tcb->state &= (!DELAY);    return( OK );}/******************************************************************************* taskIdListGet - returns a list of active task identifiers*****************************************************************************/int   taskIdListGet( int list[], int maxIds ){    v2pthread_cb_t *current_tcb;    int count;    count = 0;    /*    **  'Lock the v2pthread scheduler'    */    taskLock();    if ( (task_list != (v2pthread_cb_t *)NULL) && (list != (int *)NULL) )    {        /*        **  One or more tasks already exist in the task list...        **  Return the identifiers for the first (maxIds) tasks in the list.        **  Quit when (a) the end of the task list is reached or (b) the        **  specified capacity of the caller's ID list is reached.        */        for ( current_tcb = task_list;               current_tcb != (v2pthread_cb_t *)NULL;              current_tcb = current_tcb->nxt_task )        {            if ( count < maxIds )            {                list[count] = current_tcb->taskid;                count++;            }        }    }     /*    **  'Unlock the v2pthread scheduler'    */    taskUnlock();    return( count );}/******************************************************************************* taskIdSelf - returns the identifier of the calling task*****************************************************************************/int   taskIdSelf( void ){    v2pthread_cb_t *self_tcb;    int my_tid;    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&task_list_lock );    pthread_mutex_lock( &task_list_lock );    self_tcb = my_tcb();    pthread_cleanup_pop( 1 );    if ( self_tcb != (v2pthread_cb_t *)NULL )        my_tid = self_tcb->taskid;    else        my_tid = 0;    return( my_tid );}/******************************************************************************* taskIdVerify - indicates whether the specified task exists or not*****************************************************************************/STATUS   taskIdVerify( int taskid ){    v2pthread_cb_t *tcb;    STATUS error;    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                          (void *)&task_list_lock );    pthread_mutex_lock( &task_list_lock );    if ( taskid == 0 )        /*        **  NULL taskid specifies current task - get TCB for current task        */        tcb = my_tcb();    else        /*        **  Get TCB for task specified by taskid        */        tcb = tcb_for( taskid );    pthread_cleanup_pop( 1 );    if ( tcb != (v2pthread_cb_t *)NULL )        error = OK;    else /* NULL TCB pointer */       error = S_objLib_OBJ_ID_ERROR;    if ( error != OK )    {        errno = (int)error;        error = ERROR;    }    return( error );}/******************************************************************************* taskInit - initializes the requisite data structures to support v2pthread **            task behavior not directly supported by Posix threads.*****************************************************************************/STATUS    taskInit( v2pthread_cb_t *tcb, char *name, int pri, int opts,              char *pstack, int stksize,              int (*funcptr)( int,int,int,int,int,int,int,int,int,int ),              int arg1, int arg2, int arg3, int arg4, int arg5,              int arg6, int arg7, int arg8, int arg9, int arg10 ){    v2pthread_cb_t *current_tcb;    int i, new_priority, sched_policy;    STATUS error;    error = OK;    if ( tcb != (v2pthread_cb_t *)NULL )    {        pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,                              (void *)&task_list_lock );        pthread_mutex_lock( &task_list_lock );        /*        **  Got a new task control block.  Initialize it.        */        tcb->pthrid = (pthread_t)NULL;        /*        **  Use TCB address as task identifier        */        tcb->taskid = (int)tcb;        /*        **  Copy the task name (if any)        */        if ( name != (char *)NULL )        {            i = strlen( name ) + 1;            tcb->taskname = ts_malloc( i );            if ( tcb->taskname != (char *)NULL )                strncpy( tcb->taskname, name, i );        }        else            tcb->taskname = (char *)NULL;        /*        ** Task v2pthread priority level        */        tcb->vxw_priority = pri;        /*        **  Initialize the thread attributes to default values.        **  Then modify the attributes to make a real-time thread.        */        pthread_attr_init( &(tcb->attr) );        /*        **  Get the default scheduling priority & init prv_priority member        */        pthread_attr_getschedparam( &(tcb->attr), &(tcb->prv_priority) );        /*        **  Determine whether round-robin time-slicing is to be used or not        */        if ( roundRobinIsEnabled() )            sched_policy = SCHED_RR;        else            sched_policy = SCHED_FIFO;        pthread_attr_setschedpolicy( &(tcb->attr), sched_policy );        /*        **  Translate the v2pthread priority into a pthreads priority

⌨️ 快捷键说明

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