📄 ltasklib.c
字号:
else { /* ** Suspend the currently executing task's pthread ** if it doesn't have the scheduler locked. */ taskUnlock(); pthread_mutex_lock( &v2pthread_task_lock ); if ( scheduler_locked == pthread_self() ) { pthread_mutex_unlock( &v2pthread_task_lock ); } else { /* ** Suspend the currently executing pthread */ pthread_mutex_unlock( &v2pthread_task_lock ); self_tcb->state |= SUSPEND; pthread_kill( self_tcb->pthrid, SIGSTOP ); } } } } else error = S_objLib_OBJ_ID_ERROR; } if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* taskResume - creates a pthread to contain the specified v2pthread task and*****************************************************************************/STATUS taskResume( int tid ){ v2pthread_cb_t *current_tcb; STATUS error; error = OK; taskLock(); /* ** 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 != (v2pthread_cb_t *)NULL ) { /* ** Make task runnable if task still suspended. */ if ( current_tcb->state & SUSPEND ) { /* ** Found the task being resumed... resume it. */ current_tcb->state &= (!SUSPEND); pthread_kill( current_tcb->pthrid, SIGCONT ); } } else error = S_objLib_OBJ_ID_ERROR; taskUnlock(); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* taskPriorityGet - examines the current priority for the specified task*****************************************************************************/STATUS taskPriorityGet( int tid, int *priority ){ v2pthread_cb_t *tcb; STATUS error; error = OK; taskLock(); tcb = tcb_for( tid ); if ( tcb != (v2pthread_cb_t *)NULL ) { if ( priority != (int *)NULL ) *priority = tcb->vxw_priority; } else error = S_objLib_OBJ_ID_ERROR; taskUnlock(); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* taskPrioritySet - sets a new priority for the specified task*****************************************************************************/STATUS taskPrioritySet( int tid, int pri ){ v2pthread_cb_t *tcb; int new_priority, sched_policy; STATUS error; error = OK; taskLock(); if ( tid == 0 ) /* ** NULL tid specifies current task - get TCB for current task */ tcb = my_tcb(); else /* ** Get TCB for task specified by tid */ tcb = tcb_for( tid ); if ( tcb != (v2pthread_cb_t *)NULL ) { /* ** Translate the v2pthread priority into a pthreads priority */ pthread_attr_getschedpolicy( &(tcb->attr), &sched_policy ); new_priority = translate_priority( pri, sched_policy, &error ); /* ** Update the TCB with the new priority */ tcb->vxw_priority = pri; (tcb->prv_priority).sched_priority = new_priority; /* ** If the selected task is not the currently-executing task, ** modify the pthread's priority now. If the selected task ** IS the currently-executing task, the taskUnlock operation ** will restore this task to the new priority level. */ if ( (tid != 0) && (tcb != my_tcb()) ) { pthread_attr_setschedparam( &(tcb->attr), &(tcb->prv_priority) ); ((tcb->attr).__schedparam).sched_priority = new_priority; pthread_setschedparam( tcb->pthrid, sched_policy, (struct sched_param *)&((tcb->attr).__schedparam) ); } } else error = S_objLib_OBJ_ID_ERROR; taskUnlock(); if ( error != OK ) { errno = (int)error; error = ERROR; } return( error );}/******************************************************************************* taskName - returns the name of the specified v2pthread task*****************************************************************************/char * taskName( int tid ){ v2pthread_cb_t *current_tcb; char *taskname; pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&task_list_lock ); pthread_mutex_lock( &task_list_lock ); if ( tid == 0 ) /* ** NULL tid specifies current task - get TCB for current task */ current_tcb = my_tcb(); else /* ** Get TCB for task specified by tid */ current_tcb = tcb_for( tid ); if ( current_tcb != (v2pthread_cb_t *)NULL ) taskname = current_tcb->taskname; else taskname = (char *)NULL; pthread_cleanup_pop( 1 ); return( taskname );}/******************************************************************************* taskNametoId - identifies the named v2pthread task*****************************************************************************/int taskNameToId( char *name ){ v2pthread_cb_t *current_tcb; int tid; tid = (int)ERROR; if ( name != (char *)NULL ) { /* ** Scan the task list for a name matching the caller's name. */ pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&task_list_lock ); pthread_mutex_lock( &task_list_lock ); for ( current_tcb = task_list; current_tcb != (v2pthread_cb_t *)NULL; current_tcb = current_tcb->nxt_task ) { if ( (strcmp( name, current_tcb->taskname )) == 0 ) { /* ** A matching name was found... return its TID */ tid = current_tcb->taskid; break; } } pthread_cleanup_pop( 1 ); } return( tid );}/******************************************************************************* taskDelete - removes the specified task(s) from the task list,** frees the memory occupied by the task control block(s),** and kills the pthread(s) associated with the task(s).*****************************************************************************/STATUS taskDelete( int tid ){ v2pthread_cb_t *current_tcb; v2pthread_cb_t *self_tcb; int task_deletable; STATUS error; error = OK; taskLock(); /* ** Get pointer to TCB for specified task */ self_tcb = my_tcb(); if ( tid == 0 ) current_tcb = self_tcb; else current_tcb = tcb_for( tid ); /* ** Verify that specified task still exists in task list. */ if ( current_tcb != (v2pthread_cb_t *)NULL ) {#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - lock delete cond var mutex @ tcb %p", current_tcb );#endif /* ** Lock mutex for task delete_safe_count & condition variable */ pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&( current_tcb->tdelete_lock)); pthread_mutex_lock( &( current_tcb->tdelete_lock) ); if ( current_tcb->delete_safe_count > 0 ) task_deletable = FALSE; else task_deletable = TRUE; /* ** Unlock the mutex for the condition variable and clean up. */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - unlock delete cond var mutex @ tcb %p", current_tcb );#endif pthread_cleanup_pop( 1 ); if ( task_deletable == FALSE ) { if ( current_tcb == self_tcb ) { /* ** Task being deleted is currently executing task, and is ** delete-protected at this time... ** Task cannot block or delete itself while delete-protected. */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - can't self-delete prot task @ tcb %p", current_tcb );#endif error = S_objLib_OBJ_UNAVAILABLE; } else { /* ** Specified task is a different task, but not deletable. ** Our task must pend until the specified task becomes ** deletable. Add our task to the list of tasks waiting to ** delete the specified task. */#ifdef DIAG_PRINTFS printf( "\r\ntask @ %p wait on task-delete list @ %p", self_tcb, &(current_tcb->first_susp) );#endif link_susp_tcb( &(current_tcb->first_susp), self_tcb ); /* ** Lock mutex for task delete_safe_count & condition variable */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - lock delete cond var mutex @ tcb %p", current_tcb );#endif pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&( current_tcb->tdelete_lock)); pthread_mutex_lock( &( current_tcb->tdelete_lock) ); /* ** Unlock scheduler to allow other tasks to make specified ** task deletable. */ taskUnlock(); /* ** Wait without timeout for task to become deletable. */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - wait till task @ tcb %p deletable", current_tcb );#endif while ( current_tcb->delete_safe_count > 0 ) { pthread_cond_wait( &(current_tcb->t_deletable), &(current_tcb->tdelete_lock) ); }#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - task @ tcb %p now deletable", current_tcb );#endif taskLock(); /* ** Remove the calling task's tcb from the pended task list ** for the task being deleted. Clear the calling task 's ** suspend list pointer since the TCB it was suspended on is ** being deleted and deallocated. */ unlink_susp_tcb( &(current_tcb->first_susp), self_tcb ); self_tcb->suspend_list = (v2pthread_cb_t **)NULL; /* ** If our task was the last one pended, signal the task ** which enabled the deletion and indicate that all pended ** tasks have been awakened. */ if ( current_tcb->first_susp == (v2pthread_cb_t *)NULL ) { /* ** Lock mutex for task delete broadcast completion */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - lock del bcast mutex @ tcb %p", current_tcb );#endif pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&(current_tcb->dbcst_lock) ); pthread_mutex_lock( &(current_tcb->dbcst_lock) ); /* ** Signal task delete broadcast completion. */#ifdef DIAG_PRINTFS printf( "\r\ntaskDelete - bcast delete complt @ tcb %p", current_tcb );#endif pthread_cond_broadcast( &(current_tcb->delete_bcplt) ); /* ** Unlock the task delete broadcast
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -