/*
    $Id: settaskpri.c 1.1 1995/12/17 21:37:10 digulla Exp digulla $
    $Log: settaskpri.c $
 * Revision 1.1  1995/12/17  21:37:10  digulla
 * Initial revision
 *
    Desc:
    Lang: english
*/
#include "exec_intern.h"

/*****************************************************************************

    NAME */
	#include <clib/exec_protos.h>

	__AROS_LH2(BYTE, SetTaskPri,

/*  SYNOPSIS */
	__AROS_LA(struct Task *, task, A1),
	__AROS_LA(long         , priority, D0),

/*  LOCATION */
	struct ExecBase *, SysBase, 50, Exec)

/*  FUNCTION
	Change the priority of a given task. As a general rule the higher
	the priority the more CPU time a task gets. Useful values are within
	-127 to 5.

    INPUTS
	task	 - Pointer to task structure.
	priority - New priority of the task.

    RESULT
	Old task priority.

    NOTES

    EXAMPLE

    BUGS

    SEE ALSO

    INTERNALS

    HISTORY
	29-10-95    digulla automatically created from
			    exec_lib.fd and clib/exec_protos.h
	17-12-95    digulla Incorporated code by Matthias Fleischner

*****************************************************************************/
{
    __AROS_FUNC_INIT
    BYTE old;

    /* Always Disable() when doing something with task lists. */
    Disable();

    /* Get returncode */
    old=task->tc_Node.ln_Pri;

    /* Set new value. */
    task->tc_Node.ln_Pri=priority;

    /* Check if the task is willing to run. */
    if(task->tc_State!=TS_WAIT)
    {
	/* If it is in the ready list remove and reinsert it. */
	if(task->tc_State==TS_READY)
	{
	    Remove(&task->tc_Node);
	    Enqueue(&SysBase->TaskReady,&task->tc_Node);
	}

	/*
	    I could check the task priorities here to determine if
	    the following is really necessary, but OTOH priority
	    changes are rare and the hassle isn't really worth it.
	*/

	/* Are taskswitches allowed? */
	if(SysBase->TDNestCnt>=0||SysBase->IDNestCnt>0)
	    /* No. Store it for later. */
	    SysBase->AttnResched|=0x80;
	else
	{
	    /* Switches are allowed. Move the current task away. */
	    SysBase->ThisTask->tc_State=TS_READY;
	    Enqueue(&SysBase->TaskReady,&SysBase->ThisTask->tc_Node);

	    /* And force a rescedule. */
	    Switch();
	}
    }

    /* All done. */
    Enable();
    return old;
    __AROS_FUNC_EXIT
} /* SetTaskPri */
