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

📄 task.c

📁 linux环境支持psos的操作系统。非常适合进行移植的朋友。
💻 C
📖 第 1 页 / 共 4 页
字号:
        /*        **  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 + -