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

📄 task.c

📁 linux环境支持psos的操作系统。非常适合进行移植的朋友。
💻 C
📖 第 1 页 / 共 4 页
字号:
    sleep( 1 );#endif    (*task_ptr)( parmblk->parms[0], parmblk->parms[1], parmblk->parms[2],                 parmblk->parms[3] );    /*    **  Note: here the arg is '1'.
    **  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 t_delete takes no action if the task has already been deleted.    */    t_delete( tcb->taskid );    return( (void *)NULL );}/******************************************************************************* t_create - creates a pthread to contain the specified p2pthread task and**               initializes the requisite data structures to support p2pthread **               task behavior not directly supported by Posix threads.*****************************************************************************/ULONG    t_create( char name[4], ULONG pri, ULONG sstack, ULONG ustack, ULONG mode,              ULONG *tid ){    p2pthread_cb_t *tcb;    p2pthread_cb_t *current_tcb;    int i, new_priority;    ULONG error, my_tid;    error = ERR_NO_ERROR;    /*    **  Establish task identifier    */    my_tid = new_tid();    if ( tid != (ULONG *)NULL )        *tid = my_tid;    /* First allocate memory for a new pthread task control block */    tcb = ts_malloc( sizeof( p2pthread_cb_t ) );    if ( tcb != (p2pthread_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;        tcb->taskid = my_tid;        /*        **  Copy the task name        */        for ( i = 0; i < 4; i++ )            tcb->taskname[i] = name[i];        /*        **  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) );        /*        **  Translate the p2pthread priority into a pthreads priority        **  and set the new scheduling priority.        */        pthread_attr_setschedpolicy( &(tcb->attr), SCHED_FIFO );        new_priority = translate_priority( pri, SCHED_FIFO, &error );        (tcb->prv_priority).sched_priority = new_priority;        pthread_attr_setschedparam( &(tcb->attr), &(tcb->prv_priority) );        /*        ** 'Registers' for task        */        for ( i = 1; i < 8; i++ )            tcb->registers[i] = (ULONG)NULL;        /*        ** Mutex and Condition variable for task events        */        pthread_mutex_init( &(tcb->event_lock), (pthread_mutexattr_t *)NULL );        pthread_cond_init( &(tcb->event_change), (pthread_condattr_t *)NULL );        /*        ** Event state to awaken task (if suspended)        */        tcb->event_mask = (ULONG)NULL;        /*        ** Current state of captured event flags for task        */        tcb->events_captured = (ULONG)NULL;        /*        ** Current state of pending event flags for task        */        tcb->events_pending = (ULONG)NULL;        /*        **  The task is initially created in a suspended state        */        tcb->suspend_reason = WAIT_TSTRT;        tcb->suspend_list = (p2pthread_cb_t **)NULL;        tcb->nxt_susp = (p2pthread_cb_t *)NULL;        tcb->nxt_task = (p2pthread_cb_t *)NULL;        /*        **  If everything's okay thus far, we have a valid TCB ready to go.        */        if ( error == ERR_NO_ERROR )        {            /*            **  Insert the task control block into the task list.            **  First see if the task list contains any tasks yet.            */            if ( task_list == (p2pthread_cb_t *)NULL )            {                task_list = tcb;            }            else            {                /*                **  Append the new tcb to the task list.                */                for ( current_tcb = task_list;                      current_tcb->nxt_task != (p2pthread_cb_t *)NULL;                      current_tcb = current_tcb->nxt_task );                current_tcb->nxt_task = tcb;            }        }        else        {            /*            **  OOPS! Something went wrong... clean up & exit.            */            ts_free( (void *)tcb );        }        pthread_mutex_unlock( &task_list_lock );        pthread_cleanup_pop( 0 );    }    else /* malloc failed */    {       error = ERR_OBJTFULL;    }    return( error );}/******************************************************************************* t_start - creates a pthread to contain the specified p2pthread task and**               initializes the requisite data structures to support p2pthread **               task behavior not directly supported by Posix threads.*****************************************************************************/ULONG    t_start( ULONG tid, ULONG mode,             void (*task)( ULONG, ULONG, ULONG, ULONG ), ULONG parms[4] ){    p2pthread_cb_t *tcb;    p2pthread_pb_t *parmblk;    int sched_policy;    ULONG error;    error = ERR_NO_ERROR;    /*    **  'Lock the p2pthread scheduler' to defer any context switch to a higher    **  priority task until after this call has completed its work.    */    sched_lock();    tcb = tcb_for( tid );    if ( tcb != (p2pthread_cb_t *)NULL )    {        /*        **  Found our task control block.        **  Init the parameter block for the task wrapper function and        **  start a new real-time pthread for the task.         */        if ( tcb->suspend_reason == WAIT_TSTRT )        {            tcb->suspend_reason = WAIT_READY;            tcb->entry_point = task;            /*            ** Mode flags for task            */            tcb->flags = mode;            pthread_attr_init(&(tcb->attr));            /*            **  Determine whether round-robin time-slicing is to be used or not            */            if ( mode & T_TSLICE )                sched_policy = SCHED_RR;            else                sched_policy = SCHED_FIFO;            pthread_attr_setschedpolicy( &(tcb->attr), sched_policy );            parmblk =                  (p2pthread_pb_t *)ts_malloc( sizeof( p2pthread_pb_t ) );            if ( parmblk != (p2pthread_pb_t *)NULL )            {                parmblk->tcb = tcb;                parmblk->task_ptr = task;                if ( parms != (ULONG *)NULL )                {                    parmblk->parms[0] = parms[0];                    parmblk->parms[1] = parms[1];                    parmblk->parms[2] = parms[2];                    parmblk->parms[3] = parms[3];                }                else                {                    parmblk->parms[0] = (ULONG)NULL;                    parmblk->parms[1] = (ULONG)NULL;                    parmblk->parms[2] = (ULONG)NULL;                    parmblk->parms[3] = (ULONG)NULL;                }#ifdef DIAG_PRINTFS                 printf( "\r\nt_start task @ %p tcb @ %p:", task, tcb );#endif//                if ( pthread_create( &(tcb->pthrid), &(tcb->attr),//                                     task_wrapper, (void *)parmblk ) != 0 )                if ( pthread_create( &(tcb->pthrid), NULL,                                     task_wrapper, (void *)parmblk ) != 0 )                {#ifdef DIAG_PRINTFS                     perror( "\r\nt_start pthread_create returned error:" );#endif                    error = ERR_OBJDEL;                    tcb_delete( tcb );                }            }            else            {#ifdef DIAG_PRINTFS                 printf( "\r\nt_start unable to allocate parameter block" );#endif                error = ERR_OBJDEL;                tcb_delete( tcb );            }        }        else        {            /*            ** task already made runnable            */            error = ERR_ACTIVE;#ifdef DIAG_PRINTFS             printf( "\r\nt_start task @ tcb %p already active", tcb );#endif        }    }    else        error = ERR_OBJDEL;    /*    **  'Unlock the p2pthread scheduler' to enable a possible context switch    **  to a task made runnable by this call.    */    sched_unlock();    return( error );}/******************************************************************************* t_suspend - suspends the specified p2pthread task*****************************************************************************/ULONG    t_suspend( ULONG tid ){    p2pthread_cb_t *current_tcb;    p2pthread_cb_t *self_tcb;    ULONG error;    error = ERR_NO_ERROR;    self_tcb = my_tcb();    if ( tid == 0 )    {        /*        **  Suspend currently executing task... get its pthread ID        */        if ( self_tcb != (p2pthread_cb_t *)NULL )        {            /*            **  Don't suspend if currently executing task has the            **  scheduler locked!            */            pthread_mutex_lock( &p2pt_sched_lock );            if ( scheduler_locked == pthread_self() )            {                if ( sched_lock_level < 1L )                {                    /*                    **  Suspend the currently executing task's pthread                    */                    pthread_mutex_unlock( &p2pt_sched_lock );                    self_tcb->suspend_reason = WAIT_TSUSP;                    pthread_kill( self_tcb->pthrid, SIGSTOP );                }                else
				    /*
					**  Note: it seems that this condition did not suspend 
					**  the task and no errno returned.
					*/                    pthread_mutex_unlock( &p2pt_sched_lock );            }            else            {                /*                **  Suspend the currently executing task's pthread                */                pthread_mutex_unlock( &p2pt_sched_lock );                self_tcb->suspend_reason = WAIT_TSUSP;                pthread_kill( self_tcb->pthrid, SIGSTOP );            }        }    }    else    {        /*        **  Suspend the task whose taskid matches tid.        **  If the task_list contains tasks, scan it for the tcb        **  whose task id matches the one to be suspended.        */        current_tcb = tcb_for( tid );        if ( current_tcb != (p2pthread_cb_t *)NULL )        {            /*            **  Suspend task if task not already suspended.            */            if ( current_tcb->suspend_reason != WAIT_TSUSP )            {
			    /* 
			    ** set this pthread as the hignest priority, so 
			       that the tid task are not locked.
				*/                sched_lock();                /*                **  Found the task being suspended... suspend it.                */                if ( current_tcb != self_tcb )                {                    /*                    **  Task being suspended is not the current task.                    */                    current_tcb->suspend_reason = WAIT_TSUSP;                    pthread_kill( current_tcb->pthrid, SIGSTOP );                    sched_unlock();                }                else                {                    /*                    **  Suspend the currently executing task's pthread                    **  if it doesn't have the scheduler locked.                    */                    sched_unlock();                    pthread_mutex_lock( &p2pt_sched_lock );                    if ( scheduler_locked == pthread_self() )                    {                        pthread_mutex_unlock( &p2pt_sched_lock );                    }                    else                    {                        /*                        **  Suspend the currently executing pthread                        */                        pthread_mutex_unlock( &p2pt_sched_lock );                        self_tcb->suspend_reason = WAIT_TSUSP;                        pthread_kill( self_tcb->pthrid, SIGSTOP );                    }                }            }            else            {                error = ERR_SUSP;            }        }        else            error = ERR_OBJDEL;    }     return( error );}/******************************************************************************* t_resume - resume the specified p2pthread task
*****************************************************************************/ULONG    t_resume( ULONG tid ){    p2pthread_cb_t *current_tcb;    p2pthread_cb_t *self_tcb;    ULONG error;    error = ERR_NO_ERROR;    sched_lock();    self_tcb = my_tcb();    /*    **  Resume the task whose taskid matches tid.    **  If the task_list contains tasks, scan it for the tcb    **  whose task id matches the one to be resumed.    */    current_tcb = tcb_for( tid );    if ( current_tcb != (p2pthread_cb_t *)NULL )    {

⌨️ 快捷键说明

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