📄 task.c
字号:
/* ** Make task runnable if task still suspended. */ if ( current_tcb->suspend_reason == WAIT_TSUSP ) { /* ** Found the task being resumed... resume it. */ current_tcb->suspend_reason = WAIT_READY; pthread_kill( current_tcb->pthrid, SIGCONT ); } else { error = ERR_NOTSUSP; } } else error = ERR_OBJDEL; sched_unlock(); return( error );}/******************************************************************************* t_getreg - retrieves the contents of the specified task notepad register*****************************************************************************/ULONG t_getreg( ULONG tid, ULONG regnum, ULONG *reg_value ){ p2pthread_cb_t *current_tcb; p2pthread_cb_t *self_tcb; ULONG error; /* ** First ensure that the specified register is within range. ** ( We only support the eight user registers here. ) */ if ( regnum < NUM_TASK_REGS ) { error = ERR_NO_ERROR; sched_lock(); if ( tid == 0 ) { /* ** Use the notepad register set for the current task. */ self_tcb = my_tcb(); if ( self_tcb != (p2pthread_cb_t *)NULL ) { /* ** Retrieve the value from the specified notepad register. */ *reg_value = self_tcb->registers[regnum]; } else error = ERR_OBJDEL; } else { /* ** If the task_list contains tasks, scan it for the tcb ** whose task id matches the one specified. */ current_tcb = tcb_for( tid ); if ( current_tcb != (p2pthread_cb_t *)NULL ) { /* ** Found the specified task. Retrieve the ** value from the specified notepad register. */ *reg_value = current_tcb->registers[regnum]; } else error = ERR_OBJDEL; } sched_unlock(); } else { /* ** Unsupported register was specified. */ error = ERR_REGNUM; } return( error );}/******************************************************************************* t_setreg - overwrites the contents of the specified task notepad register** with the specified reg_value.*****************************************************************************/ULONG t_setreg( ULONG tid, ULONG regnum, ULONG reg_value ){ p2pthread_cb_t *current_tcb; p2pthread_cb_t *self_tcb; ULONG error; /* ** First ensure that the specified register is within range. ** ( We only support the eight user registers here. ) */ if ( regnum < NUM_TASK_REGS ) { error = ERR_NO_ERROR; sched_lock(); if ( tid == 0 ) { /* ** Use the notepad register set for the current task */ self_tcb = my_tcb(); if ( self_tcb != (p2pthread_cb_t *)NULL ) { /* ** Write the caller's value to the specified notepad register. */ self_tcb->registers[regnum] = reg_value; } else error = ERR_OBJDEL; } else { /* ** If the task_list contains tasks, scan it for the tcb ** whose task id matches the one specified. */ current_tcb = tcb_for( tid ); if ( current_tcb != (p2pthread_cb_t *)NULL ) { /* ** Found the specified task. Write the caller's ** value to the specified register. */ current_tcb->registers[regnum] = reg_value; } else error = ERR_OBJDEL; } sched_unlock(); } else { /* ** Unsupported register was specified. */ error = ERR_REGNUM; } return( error );}/******************************************************************************* t_setpri - sets a new priority for the specified task*****************************************************************************/ULONG t_setpri( ULONG tid, ULONG pri, ULONG *oldpri ){ p2pthread_cb_t *tcb; int new_priority, sched_policy; ULONG error; error = ERR_NO_ERROR; sched_lock(); tcb = tcb_for( tid ); if ( tcb != (p2pthread_cb_t *)NULL ) { /* ** Save the previous priority level if the caller wants it. */ if ( oldpri != (ULONG *)NULL ) *oldpri = (ULONG)(tcb->prv_priority).sched_priority; /* ** Translate the p2pthread 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->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 sched_unlock operation ** will restore this task to the new priority level. */ if ( (tid != 0) && (tcb != my_tcb()) ) { pthread_attr_setschedparam( &(tcb->attr), &(tcb->prv_priority) ); } } else error = ERR_OBJDEL; sched_unlock(); return( error );}/******************************************************************************* t_mode - sets the value of the calling task's mode flags*****************************************************************************/ULONG t_mode( ULONG mask, ULONG new_flags, ULONG *old_flags ){ p2pthread_cb_t *tcb; int sched_policy; ULONG error; error = ERR_NO_ERROR; pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&task_list_lock ); pthread_mutex_lock( &task_list_lock ); tcb = my_tcb(); if ( tcb != (p2pthread_cb_t *)NULL ) { /* ** Save the previous priority level if the caller wants it. */ if ( old_flags != (ULONG *)NULL ) *old_flags = tcb->flags; /* ** Change the task preemptibility status if specified ** to either allow the task to be preempted or to prevent ** preemption. */ pthread_mutex_unlock( &task_list_lock );
/*
** Note: modified from (mask & T_NOPREEMPT).
*/ if (mask & T_NOPREEMPT)
{ if ( (new_flags & T_NOPREEMPT) ) { if ( !(tcb->flags & T_NOPREEMPT) ) sched_lock(); } else { if ( (tcb->flags & T_NOPREEMPT) ) sched_unlock(); } } /* ** Determine whether round-robin time-slicing is to be used or not */ pthread_mutex_lock( &task_list_lock );
/*
** Note: modified from (mask & T_TSLICE).
*/ if (mask & T_TSLICE) { if ( new_flags & T_TSLICE ) sched_policy = SCHED_RR; else sched_policy = SCHED_FIFO; pthread_attr_setschedpolicy( &(tcb->attr), sched_policy ); pthread_setschedparam( tcb->pthrid, sched_policy, (struct sched_param *)&((tcb->attr).__schedparam) ); } /* ** Update the mode flag bits in the TCB. First clear all the ** masked bits and then OR in the new bits. */ tcb->flags &= (~mask); tcb->flags |= (new_flags & mask); } else error = ERR_OBJDEL; pthread_mutex_unlock( &task_list_lock ); pthread_cleanup_pop( 0 ); return( error );}/******************************************************************************* t_ident - identifies the specified p2pthread task*****************************************************************************/ULONG t_ident( char name[4], ULONG node, ULONG *tid ){ p2pthread_cb_t *current_tcb; ULONG error; error = ERR_NO_ERROR; /* ** Validate the node specifier... only zero is allowed here. */ if ( node != 0L ) error = ERR_NODENO; else { /* ** If task name string is a NULL pointer, return TID of current task. */ if ( name == (char *)NULL ) { current_tcb = my_tcb(); *tid = current_tcb->taskid; } else { /* ** Scan the task list for a name matching the caller's name. */ for ( current_tcb = task_list; current_tcb != (p2pthread_cb_t *)NULL; current_tcb = current_tcb->nxt_task ) { if ( (strncmp( name, current_tcb->taskname, 4 )) == 0 ) { /* ** A matching name was found... return its TID */ *tid = current_tcb->taskid; break; } } if ( current_tcb == (p2pthread_cb_t *)NULL ) { /* ** No matching name found... return caller's TID with error. */ current_tcb = my_tcb(); *tid = current_tcb->taskid; error = ERR_OBJNF; } } } return( error );}/******************************************************************************* system initialization pthread*****************************************************************************//*void *init_system( void *dummy ){ user_sysroot(); return( (void *)NULL );}*/ /******************************************************************************* p2pthread main program**** This function serves as the entry point to the p2pthread emulation** environment. It serves as the parent process to all p2pthread tasks.** This process creates an initialization thread and sets the priority of** that thread to the highest allowable value. This allows the initialization** thread to complete its work without being preempted by any of the task** threads it creates.*****************************************************************************//*int main( int argc, char **argv ){ int max_priority; pthread_t tid_init; pthread_attr_t init_attr; struct sched_param init_priority;*/ /* ** Get the maximum permissible priority level for the current OS. */// max_priority = sched_get_priority_max( SCHED_FIFO ); /* ** Lock all memory pages associated with this process to prevent delays ** due to process (or thread) memory being swapped out to disk and back. */// mlockall( (MCL_CURRENT | MCL_FUTURE) ); /* ** Initialize the thread attributes to default values. ** Then modify the attributes to make a real-time thread. */// pthread_attr_init( &init_attr );// pthread_attr_setschedpolicy( &init_attr, SCHED_FIFO ); /* ** Get the default scheduling priority & init init_priority ** This makes the initialization pthread the highest-priority thread ** in the p2pthread environment, and prevents premature preemption. *//* pthread_attr_getschedparam( &init_attr, &init_priority ); init_priority.sched_priority = max_priority; pthread_attr_setschedparam( &init_attr, &init_priority ); printf( "\r\nStarting System Initialization Pthread" ); pthread_create( &tid_init, &init_attr, init_system, (void *)NULL );*/ /* ** Wait for the initialization thread to terminate and return. */ // pthread_join( tid_init, (void **)NULL );// exit( 0 );//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -