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

📄 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 + -