forked from Imagelibrary/rtems
Committed modifications from ITRON Task and Task Dependendent Synchronization
Working Group. Included are tests.
This commit is contained in:
@@ -19,14 +19,12 @@ extern "C" {
|
||||
* off the shell programs including paranoia.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
typedef signed8 B; /* signed 8-bit integer */
|
||||
typedef signed16 H; /* signed 16-bit integer */
|
||||
typedef signed32 W; /* signed 32-bit integer */
|
||||
typedef unsigned8 UB; /* unsigned 8-bit integer */
|
||||
typedef unsigned16 UH; /* unsigned 16-bit integer */
|
||||
typedef unsigned32 UW; /* unsigned 32-bit integer */
|
||||
#endif
|
||||
|
||||
typedef unsigned32 VW; /* unpredictable data type (32-bit size) */
|
||||
typedef unsigned16 VH; /* unpredictable data type (16-bit size) */
|
||||
|
||||
@@ -80,7 +80,7 @@ typedef Objects_Control ITRON_Objects_Control;
|
||||
#define _ITRON_Objects_Clarify_get_id_error( _the_information, _id ) \
|
||||
(((_id) < -4) ? E_OACV : /* attempt to access a "system object" */ \
|
||||
((_id) <= 0) ? E_ID : /* bogus index of 0 - -3 */ \
|
||||
((_id) <= (_the_information)->maximum) ? E_OBJ : /* object is in use */ \
|
||||
((_id) <= (_the_information)->maximum) ? E_NOEXS : /* does not exist */ \
|
||||
E_ID) /* simply a bad id */
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,18 @@ ER _ITRON_Delete_task(
|
||||
Thread_Control *the_thread
|
||||
);
|
||||
|
||||
/* XXX remove the need for this. Enable dispatch should not be hidden */
|
||||
|
||||
#define _ITRON_return_errorno( _errno ) \
|
||||
do { \
|
||||
_Thread_Enable_dispatch(); \
|
||||
return _errno; \
|
||||
} while (0);
|
||||
|
||||
|
||||
#ifndef __RTEMS_APPLICATION__
|
||||
#include <rtems/itron/task.inl>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -109,7 +109,13 @@ RTEMS_INLINE_ROUTINE Thread_Control *_ITRON_Task_Get (
|
||||
ID id,
|
||||
Objects_Locations *location
|
||||
)
|
||||
{
|
||||
{
|
||||
if ( id == 0 ) {
|
||||
_Thread_Disable_dispatch();
|
||||
*location = OBJECTS_LOCAL;
|
||||
return _Thread_Executing;
|
||||
}
|
||||
|
||||
return (Thread_Control *)
|
||||
_ITRON_Objects_Get( &_ITRON_Task_Information, id, location );
|
||||
}
|
||||
@@ -144,17 +150,29 @@ RTEMS_INLINE_ROUTINE boolean _ITRON_Task_Is_null (
|
||||
* _ITRON_tasks_Priority_to_Core
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE Priority_Control _ITRON_Task_Priority_to_Core(
|
||||
PRI _priority
|
||||
RTEMS_INLINE_ROUTINE _ITRON_Task_Priority_to_Core(
|
||||
PRI ITRON_priority
|
||||
)
|
||||
{
|
||||
return ((Priority_Control) (_priority));
|
||||
return (Priority_Control) ITRON_priority;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _ITRON_tasks_Core_to_Priority
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE _ITRON_Task_Core_to_Priority(
|
||||
Priority_Control core_priority
|
||||
)
|
||||
{
|
||||
return (PRI) core_priority;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ ER can_wup(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* XXX - FILL ME IN.
|
||||
*/
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,44 @@ ER chg_pri(
|
||||
PRI tskpri
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
Priority_Control new_priority;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
return -1;
|
||||
|
||||
if (( tskpri <= 0 ) || ( tskpri >= 256 ))
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ));
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
new_priority = _ITRON_Task_Priority_to_Core( tskpri );
|
||||
the_thread->real_priority = new_priority;
|
||||
|
||||
/*
|
||||
* XXX This is from the rtems side and I'm not sure what this is for.
|
||||
* XXX Is this check right or should change priority be called
|
||||
* regardless?
|
||||
*/
|
||||
|
||||
if ( the_thread->resource_count == 0 ||
|
||||
the_thread->current_priority > new_priority )
|
||||
_Thread_Change_priority( the_thread, new_priority, FALSE );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,28 +21,6 @@
|
||||
* cre_tsk - Create Task
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX - How do I return these errors ??? Do I have to validate the ID
|
||||
prior to calling the ID routine ??
|
||||
E_NOMEM Insufficient memory (Memory for control block and/or user stack
|
||||
cannot be allocated)
|
||||
E_ID Invalid ID Number (tskid was invalid or could not be used)
|
||||
E_RSATR Reserved attribute (tskatr was invalid or could not be used)
|
||||
E_OBJ Invalid object state (a task of the same ID already exists)
|
||||
E_OACV Object access violation (A tskid less than -4 was specified from
|
||||
a user task. This is implementation dependent.)
|
||||
E_PAR Parameter error (pk_ctsk, task, itskpri and/or stksz is invalid)
|
||||
EN_OBJNO An object number which could not be accessed on the target node
|
||||
is specified.
|
||||
EN_CTXID Specified an object on another node when the system call was
|
||||
issued from a task in dispatch disabled state or from a task-
|
||||
independent portion
|
||||
EN_PAR A value outside the range supported by the target node and/or
|
||||
transmission packet format was specified as a parameter (a value
|
||||
outside supported range was specified for exinf, tskatr, task,
|
||||
itskpri and/or stksz)
|
||||
*/
|
||||
|
||||
ER cre_tsk(
|
||||
ID tskid,
|
||||
T_CTSK *pk_ctsk
|
||||
@@ -59,19 +37,40 @@ ER cre_tsk(
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/*
|
||||
* Validate Parameters.
|
||||
*/
|
||||
|
||||
if ( pk_ctsk == NULL )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
if ((pk_ctsk->tskatr != TA_ASM ) &&
|
||||
(pk_ctsk->tskatr != TA_HLNG) &&
|
||||
(pk_ctsk->tskatr != TA_COP0) &&
|
||||
(pk_ctsk->tskatr != TA_COP1) &&
|
||||
(pk_ctsk->tskatr != TA_COP2) &&
|
||||
(pk_ctsk->tskatr != TA_COP3) &&
|
||||
(pk_ctsk->tskatr != TA_COP4) &&
|
||||
(pk_ctsk->tskatr != TA_COP5) &&
|
||||
(pk_ctsk->tskatr != TA_COP6) &&
|
||||
(pk_ctsk->tskatr != TA_COP7))
|
||||
_ITRON_return_errorno( E_RSATR );
|
||||
|
||||
if (( pk_ctsk->itskpri <= 0 ) || ( pk_ctsk->itskpri >= 256 ))
|
||||
if ( pk_ctsk->itskpri <= 0 )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
if ( pk_ctsk->task == NULL )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
if ( pk_ctsk->stksz < 0 )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
/*
|
||||
* allocate the thread.
|
||||
*/
|
||||
|
||||
the_thread = _ITRON_Task_Allocate( tskid );
|
||||
if ( !the_thread ) {
|
||||
ena_dsp();
|
||||
return _ITRON_Task_Clarify_allocation_id_error( tskid );
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - FIX THE VARIABLES TO THE CORRECT VALUES!!!
|
||||
*/
|
||||
if ( !the_thread )
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_allocation_id_error( tskid ) );
|
||||
|
||||
/*
|
||||
* Initialize the core thread for this task.
|
||||
@@ -83,7 +82,7 @@ ER cre_tsk(
|
||||
the_thread,
|
||||
NULL,
|
||||
pk_ctsk->stksz,
|
||||
TRUE, /* XXX - All tasks FP ??? */
|
||||
TRUE, /* XXX - All tasks FP for now */
|
||||
core_priority,
|
||||
TRUE,
|
||||
THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE,
|
||||
@@ -94,22 +93,9 @@ ER cre_tsk(
|
||||
|
||||
if ( !status ) {
|
||||
_ITRON_Task_Free( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return -1;
|
||||
#if (0)
|
||||
/* XXX */
|
||||
#endif
|
||||
_ITRON_return_errorno( E_NOMEM );
|
||||
}
|
||||
|
||||
#if (0) /* XXX We have any thing else to set per API structure? */
|
||||
api = the_thread->API_Extensions[ THREAD_API_ITRON ];
|
||||
asr = &api->Signal;
|
||||
|
||||
asr->is_enabled = FALSE;
|
||||
|
||||
*id = the_thread->Object.id;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This insures we evaluate the process-wide signals pending when we
|
||||
* first run.
|
||||
@@ -125,3 +111,6 @@ ER cre_tsk(
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,16 +29,21 @@ ER del_tsk(
|
||||
Objects_Locations location;
|
||||
ER result;
|
||||
|
||||
/* XXX - Fix Documentation and error checking for this error on self */
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_Thread_Enable_dispatch();
|
||||
return _ITRON_Task_Clarify_get_id_error( tskid );
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
result = _ITRON_Delete_task( the_thread );
|
||||
|
||||
@@ -25,13 +25,13 @@ void exd_tsk( void )
|
||||
{
|
||||
Objects_Information *the_information;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_information = _Objects_Get_information( _Thread_Executing->Object.id );
|
||||
|
||||
/* This should never happen if _Thread_Get() works right */
|
||||
assert( the_information );
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
_Thread_Set_state( _Thread_Executing, STATES_DORMANT );
|
||||
_ITRON_Delete_task( _Thread_Executing );
|
||||
|
||||
|
||||
@@ -23,5 +23,10 @@
|
||||
|
||||
void ext_tsk( void )
|
||||
{
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
_Thread_Restart( _Thread_Executing, NULL, 0 );
|
||||
_Thread_Set_state( _Thread_Executing, STATES_DORMANT );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,32 @@ ER frsm_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Resume( the_thread, TRUE );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ ER get_tid(
|
||||
ID *p_tskid
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This does not support multiprocessing. The id handling will have
|
||||
* to be enhanced to support multiprocessing.
|
||||
*/
|
||||
|
||||
*p_tskid = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,59 @@ ER ref_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
Priority_Control core_priority;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if (!pk_rtsk)
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
/*
|
||||
* The following are extended functions [level X ].
|
||||
* XXX - tskwait, wid, wupcnt, and tskatr are presently not implemented.
|
||||
*/
|
||||
|
||||
pk_rtsk->tskwait = 0;
|
||||
pk_rtsk->wid = 0;
|
||||
pk_rtsk->wupcnt = 0;
|
||||
pk_rtsk->suscnt = the_thread->suspend_count;
|
||||
pk_rtsk->tskatr = 0;
|
||||
pk_rtsk->task = the_thread->Start.entry_point;
|
||||
core_priority = the_thread->Start.initial_priority;
|
||||
pk_rtsk->itskpri = _ITRON_Task_Core_to_Priority( core_priority );
|
||||
pk_rtsk->stksz = the_thread->Start.Initial_stack.size;
|
||||
|
||||
/*
|
||||
* The following are required.
|
||||
*/
|
||||
|
||||
pk_rtsk->exinf = NULL; /* extended information */
|
||||
pk_rtsk->tskpri = _ITRON_Task_Core_to_Priority(the_thread->current_priority);
|
||||
pk_rtsk->tskstat = 0;
|
||||
|
||||
/*
|
||||
* Mask in the tskstat information
|
||||
* Convert the task state XXX double check this
|
||||
*/
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
pk_rtsk->tskstat |= TTS_RUN;
|
||||
if ((the_thread->current_state & STATES_READY) != 0)
|
||||
pk_rtsk->tskstat = TTS_RDY;
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
pk_rtsk->tskstat = TTS_DMT;
|
||||
if ((the_thread->current_state & STATES_SUSPENDED) != 0)
|
||||
pk_rtsk->tskstat = TTS_SUS;
|
||||
if ((the_thread->current_state & STATES_BLOCKED) != 0)
|
||||
pk_rtsk->tskstat = TTS_WAI;
|
||||
|
||||
return E_OK; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,30 @@ ER rel_wai(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_Thread_Enable_dispatch();
|
||||
return _ITRON_Task_Clarify_get_id_error( tskid );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* XXX - FILL ME IN.
|
||||
*/
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,26 @@ ER rot_rdq(
|
||||
PRI tskpri
|
||||
)
|
||||
{
|
||||
PRI priority;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/*
|
||||
* Yield of processor will rotate the queue for this processor.
|
||||
*/
|
||||
|
||||
if (( tskpri <= 0 ) || ( tskpri >= 256 ))
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
priority = _ITRON_Task_Core_to_Priority(_Thread_Executing->current_priority);
|
||||
if ( priority == tskpri )
|
||||
_Thread_Yield_processor();
|
||||
else {
|
||||
_Thread_Rotate_Ready_Queue( _ITRON_Task_Core_to_Priority( tskpri ) );
|
||||
}
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,31 @@ ER rsm_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Resume( the_thread, FALSE );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* slp_tsk - Sleep Task Sleep Task with Timeout
|
||||
* slp_tsk - Sleep Task
|
||||
*/
|
||||
|
||||
ER slp_tsk( void )
|
||||
|
||||
@@ -21,24 +21,6 @@
|
||||
* sta_tsk - Start Task
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX - How Do I know when these happen ???
|
||||
E_NOEXS Object does not exist (the task specified by tskid does not exist)
|
||||
E_OACV Object access violation (A tskid less than -4 was specified from
|
||||
a user task. This is implementation dependent.)
|
||||
E_OBJ Invalid object state (the target task is not in DORMANT state)
|
||||
EN_OBJNO An object number which could not be accessed on the target node
|
||||
is specified. XXX Should never get on a single processor??
|
||||
EN_CTXID Specified an object on another node when the system call was
|
||||
issued from a task in dispatch disabled state or from a task-
|
||||
independent portionXXX Should never get on a single processor??
|
||||
EN_PAR A value outside the range supported by the target node and/or
|
||||
transmission packet format was specified as a parameter (a value
|
||||
outside supported range was specified for stacd)
|
||||
XXX- What does _ITRON_Task_Get return on an invalid id and how do you know
|
||||
if it is E_ID, E_NOEXS, E_OACV
|
||||
*/
|
||||
|
||||
ER sta_tsk(
|
||||
ID tskid,
|
||||
INT stacd
|
||||
@@ -49,10 +31,16 @@ ER sta_tsk(
|
||||
boolean status;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
return E_ID; /* XXX */
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
status = _Thread_Start(
|
||||
@@ -63,14 +51,8 @@ ER sta_tsk(
|
||||
0 /* unused */
|
||||
);
|
||||
|
||||
/*
|
||||
* Wrong state XXX
|
||||
*/
|
||||
|
||||
if ( !status ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OBJ;
|
||||
}
|
||||
if ( !status )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
|
||||
@@ -29,6 +29,33 @@ ER sus_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Suspend( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -117,10 +117,8 @@ ER _ITRON_Delete_task(
|
||||
Objects_Information *the_information;
|
||||
|
||||
the_information = _Objects_Get_information( the_thread->Object.id );
|
||||
|
||||
if ( !the_information ) {
|
||||
return -1; /* XXX */
|
||||
/* This should never happen if _Thread_Get() works right */
|
||||
return E_OBJ; /* XXX - should never happen */
|
||||
}
|
||||
|
||||
_Thread_Close( the_information, the_thread );
|
||||
|
||||
@@ -18,13 +18,37 @@
|
||||
|
||||
|
||||
/*
|
||||
* ter_tsk - Terminate Other Task
|
||||
* ter_tsk - Terminate Other Task - Set State to DORMANT
|
||||
*/
|
||||
|
||||
ER ter_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
|
||||
if ( !the_thread )
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if ( _States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
_Thread_Restart( the_thread, NULL, 0 );
|
||||
_Thread_Set_state( the_thread, STATES_DORMANT );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ rtems_status_code rtems_task_resume(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
if ( _States_Is_suspended( the_thread->current_state ) ) {
|
||||
_Thread_Resume( the_thread );
|
||||
_Thread_Resume( the_thread, TRUE );
|
||||
_Thread_Enable_dispatch();
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ rtems_status_code rtems_task_suspend(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
if ( !_States_Is_suspended( the_thread->current_state ) ) {
|
||||
_Thread_Set_state( the_thread, STATES_SUSPENDED );
|
||||
_Thread_Suspend( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ subdir = score/include/rtems/score
|
||||
RTEMS_ROOT = @RTEMS_ROOT@
|
||||
PROJECT_ROOT = @PROJECT_ROOT@
|
||||
|
||||
HAS_ITRON_API = @HAS_ITRON_API@
|
||||
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
@@ -93,8 +95,7 @@ $(TARGOPTS):
|
||||
@if test "$(HAS_POSIX_API)" = "yes"; then \
|
||||
echo "#define RTEMS_POSIX_API 1" >>$@; \
|
||||
fi
|
||||
echo "SHOULD BE HAS_ITRON_API not RTEMS_HAS_ITRON_API XXX "
|
||||
@if test "$(RTEMS_HAS_ITRON_API)" = "yes"; then \
|
||||
@if test "$(HAS_ITRON_API)" = "yes"; then \
|
||||
echo "#define RTEMS_ITRON_API 1" >>$@; \
|
||||
fi
|
||||
@if test "$(RTEMS_USE_NEWLIB)" = "yes"; then \
|
||||
|
||||
@@ -185,6 +185,7 @@ struct Thread_Control_struct {
|
||||
MP_packet_Prefix *receive_packet;
|
||||
#endif
|
||||
/****************** end of common block ********************/
|
||||
unsigned32 suspend_count;
|
||||
boolean is_global;
|
||||
boolean do_post_task_switch_extension;
|
||||
|
||||
@@ -552,6 +553,20 @@ void _Thread_Tickle_timeslice( void );
|
||||
|
||||
void _Thread_Yield_processor( void );
|
||||
|
||||
/*
|
||||
* _Thread_Rotate_Ready_Queue
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked to rotate the ready queue for the
|
||||
* given priority. It can be used to yeild the processor
|
||||
* by rotating the executing threads ready queue.
|
||||
*/
|
||||
|
||||
void _Thread_Rotate_Ready_Queue(
|
||||
Priority_Control priority
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Load_environment
|
||||
*
|
||||
@@ -623,12 +638,43 @@ void _Thread_Set_priority(
|
||||
Priority_Control new_priority
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Suspend
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine updates the related suspend fields in the_thread
|
||||
* control block to indicate the current nested level.
|
||||
*/
|
||||
|
||||
void _Thread_Suspend(
|
||||
Thread_Control *the_thread
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine updates the related suspend fields in the_thread
|
||||
* control block to indicate the current nested level. A force
|
||||
* parameter of TRUE will force a resume and clear the suspend count.
|
||||
*/
|
||||
|
||||
void _Thread_Resume(
|
||||
Thread_Control *the_thread,
|
||||
boolean force
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Evaluate_mode
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine XXX
|
||||
* This routine evaluates the current scheduling information for the
|
||||
* system and determines if a context switch is required. This
|
||||
* is usually called after changing an execution mode such as preemptability
|
||||
* for a thread.
|
||||
*/
|
||||
|
||||
boolean _Thread_Evaluate_mode( void );
|
||||
|
||||
@@ -82,24 +82,6 @@ RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing_also_the_heir( void )
|
||||
return ( _Thread_Executing == _Thread_Heir );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine clears the SUSPENDED state for the_thread. It performs
|
||||
* any necessary scheduling operations including the selection of
|
||||
* a new heir thread.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Resume (
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Thread_Clear_state( the_thread, STATES_SUSPENDED );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Unblock
|
||||
|
||||
@@ -53,15 +53,6 @@
|
||||
#define _Thread_Is_executing_also_the_heir() \
|
||||
( _Thread_Executing == _Thread_Heir )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Resume( _the_thread ) \
|
||||
_Thread_Clear_state( (_the_thread), STATES_SUSPENDED )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Unblock
|
||||
|
||||
@@ -42,10 +42,10 @@ OBJECT_C_PIECES = object objectallocate objectallocatebyindex \
|
||||
THREAD_C_PIECES = thread threadchangepriority threadclearstate threadclose \
|
||||
threadcreateidle threaddelayended threaddispatch threadevaluatemode \
|
||||
threadget threadhandler threadidlebody threadinitialize threadloadenv \
|
||||
threadready threadresettimeslice threadrestart threadsetpriority \
|
||||
threadsetstate threadsettransient threadstackallocate threadstackfree \
|
||||
threadstart threadstartmultitasking threadtickletimeslice \
|
||||
threadyieldprocessor
|
||||
threadready threadresettimeslice threadrestart threadresume \
|
||||
threadrotatequeue threadsetpriority threadsetstate threadsettransient \
|
||||
threadstackallocate threadstackfree threadstart threadstartmultitasking \
|
||||
threadsuspend threadtickletimeslice threadyieldprocessor
|
||||
|
||||
THREADQ_C_PIECES= threadq threadqdequeue threadqdequeuefifo \
|
||||
threadqdequeuepriority threadqenqueue threadqenqueuefifo \
|
||||
|
||||
@@ -153,6 +153,7 @@ boolean _Thread_Initialize(
|
||||
|
||||
the_thread->current_state = STATES_DORMANT;
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->suspend_count = 0;
|
||||
the_thread->real_priority = priority;
|
||||
the_thread->Start.initial_priority = priority;
|
||||
the_thread->ticks_executed = 0;
|
||||
|
||||
@@ -44,7 +44,8 @@ boolean _Thread_Restart(
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) ) {
|
||||
|
||||
_Thread_Set_transient( the_thread );
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->suspend_count = 0;
|
||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||
|
||||
95
c/src/exec/score/src/threadresume.c
Normal file
95
c/src/exec/score/src/threadresume.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* This kernel routine clears the SUSPEND state if the suspend_count
|
||||
* drops below one. If the force parameter is set the suspend_count
|
||||
* is forced back to zero. The thread ready chain is adjusted if
|
||||
* necessary and the Heir thread is set accordingly.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_thread - pointer to thread control block
|
||||
* force - force the suspend count back to 0
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* priority map
|
||||
* select heir
|
||||
*/
|
||||
|
||||
|
||||
void _Thread_Resume(
|
||||
Thread_Control *the_thread,
|
||||
boolean force
|
||||
)
|
||||
{
|
||||
|
||||
ISR_Level level;
|
||||
States_Control current_state;
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
if ( force == TRUE )
|
||||
the_thread->suspend_count = 0;
|
||||
else
|
||||
the_thread->suspend_count--;
|
||||
|
||||
if ( the_thread->suspend_count > 0 ) {
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
current_state = the_thread->current_state;
|
||||
if ( current_state & STATES_SUSPENDED ) {
|
||||
current_state =
|
||||
the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state);
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
|
||||
_Priority_Add_to_bit_map( &the_thread->Priority_map );
|
||||
|
||||
_Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
|
||||
_Thread_Heir = the_thread;
|
||||
if ( _Thread_Executing->is_preemptible ||
|
||||
the_thread->current_priority == 0 )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
93
c/src/exec/score/src/threadrotatequeue.c
Normal file
93
c/src/exec/score/src/threadrotatequeue.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Rotate_Ready_Queue
|
||||
*
|
||||
* This kernel routine will rotate the ready queue.
|
||||
* remove the running THREAD from the ready chain
|
||||
* and place it immediatly at the rear of this chain. Reset timeslice
|
||||
* and yield the processor functions both use this routine, therefore if
|
||||
* reset is TRUE and this is the only thread on the chain then the
|
||||
* timeslice counter is reset. The heir THREAD will be updated if the
|
||||
* running is also the currently the heir.
|
||||
*
|
||||
* Input parameters:
|
||||
* Priority of the queue we wish to modify.
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* ready chain
|
||||
* select heir
|
||||
*/
|
||||
|
||||
void _Thread_Rotate_Ready_Queue(
|
||||
Priority_Control priority
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
Chain_Control *ready;
|
||||
Chain_Node *node;
|
||||
|
||||
ready = &_Thread_Ready_chain[ priority ];
|
||||
executing = _Thread_Executing;
|
||||
|
||||
if ( ready == executing->ready ) {
|
||||
_Thread_Yield_processor();
|
||||
return;
|
||||
}
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
if ( !_Chain_Is_empty( ready ) ) {
|
||||
if (!_Chain_Has_only_one_node( ready ) ) {
|
||||
node = _Chain_Get_first_unprotected( ready );
|
||||
_Chain_Append_unprotected( ready, node );
|
||||
}
|
||||
}
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( _Thread_Heir->ready == ready )
|
||||
_Thread_Heir = (Thread_Control *) ready->first;
|
||||
|
||||
if ( executing != _Thread_Heir )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
83
c/src/exec/score/src/threadsuspend.c
Normal file
83
c/src/exec/score/src/threadsuspend.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Suspend
|
||||
*
|
||||
* This kernel routine sets the SUSPEND state in the THREAD. The
|
||||
* THREAD chain and suspend count are adjusted if necessary.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_thread - pointer to thread control block
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* ready chain
|
||||
* select map
|
||||
*/
|
||||
|
||||
void _Thread_Suspend(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Chain_Control *ready;
|
||||
|
||||
ready = the_thread->ready;
|
||||
_ISR_Disable( level );
|
||||
the_thread->suspend_count++;
|
||||
if ( !_States_Is_ready( the_thread->current_state ) ) {
|
||||
the_thread->current_state =
|
||||
_States_Set( STATES_SUSPENDED, the_thread->current_state );
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
the_thread->current_state = STATES_SUSPENDED;
|
||||
|
||||
if ( _Chain_Has_only_one_node( ready ) ) {
|
||||
|
||||
_Chain_Initialize_empty( ready );
|
||||
_Priority_Remove_from_bit_map( &the_thread->Priority_map );
|
||||
|
||||
} else
|
||||
_Chain_Extract_unprotected( &the_thread->Object.Node );
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( _Thread_Is_heir( the_thread ) )
|
||||
_Thread_Calculate_heir();
|
||||
|
||||
if ( _Thread_Is_executing( the_thread ) )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
@@ -19,7 +19,7 @@ PGM = ${ARCH}/$(TEST).exe
|
||||
MANAGERS = all
|
||||
|
||||
# C source names, if any, go here -- minus the .c
|
||||
C_PIECES = init preempt spinit task1 task2 task3
|
||||
C_PIECES = init preempt task1 task2 task3
|
||||
C_FILES = $(C_PIECES:%=%.c)
|
||||
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/* Init
|
||||
*
|
||||
* This routine is the initialization task for this test program.
|
||||
* It is a user initialization task and has the responsibility for creating
|
||||
* and starting the tasks that make up the test. If the time of day
|
||||
* clock is required for the test, it should also be set to a known
|
||||
* value by this function.
|
||||
*
|
||||
* Input parameters:
|
||||
* argument - task argument
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define TEST_INIT
|
||||
#include "system.h"
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
puts( "\n\n*** TEST 2 ***" );
|
||||
|
||||
Preempt_task_name = rtems_build_name( 'P', 'R', 'M', 'T' );
|
||||
|
||||
status = rtems_task_create(
|
||||
Preempt_task_name,
|
||||
1,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Preempt_task_id
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of RTEMS_PREEMPT" );
|
||||
|
||||
status = rtems_task_start( Preempt_task_id, Preempt_task, 0 );
|
||||
directive_failed( status, "rtems_task_start of RTEMS_PREEMPT" );
|
||||
|
||||
puts( "INIT - rtems_task_wake_after - yielding processor" );
|
||||
status = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
|
||||
directive_failed( status, "rtems_task_wake_after" );
|
||||
|
||||
Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' );
|
||||
Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' );
|
||||
Task_name[ 3 ] = rtems_build_name( 'T', 'A', '3', ' ' );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 1 ],
|
||||
3,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 1 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA1" );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 2 ],
|
||||
3,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 2 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA2" );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 3 ],
|
||||
3,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 3 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA3" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA1" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA2" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 3 ], Task_3, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA3" );
|
||||
|
||||
puts( "INIT - suspending TA2 while middle task on a ready chain" );
|
||||
status = rtems_task_suspend( Task_id[ 2 ] );
|
||||
directive_failed( status, "rtems_task_suspend of TA2" );
|
||||
|
||||
status = rtems_task_delete( Task_id[ 1 ] );
|
||||
directive_failed( status, "rtems_task_delete of TA1" );
|
||||
|
||||
status = rtems_task_delete( Task_id[ 2 ] );
|
||||
directive_failed( status, "rtems_task_delete of TA2" );
|
||||
|
||||
status = rtems_task_delete( Task_id[ 3 ] );
|
||||
directive_failed( status, "rtems_task_delete of TA3" );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 1 ],
|
||||
1,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 1 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA1" );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 2 ],
|
||||
3,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 2 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA2" );
|
||||
|
||||
status = rtems_task_create(
|
||||
Task_name[ 3 ],
|
||||
3,
|
||||
RTEMS_MINIMUM_STACK_SIZE,
|
||||
RTEMS_DEFAULT_MODES,
|
||||
RTEMS_DEFAULT_ATTRIBUTES,
|
||||
&Task_id[ 3 ]
|
||||
);
|
||||
directive_failed( status, "rtems_task_create of TA3" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA1" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA2" );
|
||||
|
||||
status = rtems_task_start( Task_id[ 3 ], Task_3, 0 );
|
||||
directive_failed( status, "rtems_task_start of TA3" );
|
||||
|
||||
status = rtems_task_delete( RTEMS_SELF );
|
||||
directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
|
||||
}
|
||||
@@ -31,6 +31,11 @@ RTEMS_ENABLE_HWAPI
|
||||
RTEMS_CHECK_CPU
|
||||
RTEMS_CANONICAL_HOST
|
||||
|
||||
RTEMS_CHECK_POSIX_API(RTEMS_BSP)
|
||||
RTEMS_CHECK_ITRON_API(RTEMS_BSP)
|
||||
RTEMS_CHECK_NETWORKING(RTEMS_BSP)
|
||||
RTEMS_CHECK_RDBG
|
||||
|
||||
AC_CONFIG_SUBDIRS(tools/build)
|
||||
AC_CONFIG_SUBDIRS(tools/update)
|
||||
AC_CONFIG_SUBDIRS(tools/cpu)
|
||||
|
||||
@@ -19,14 +19,12 @@ extern "C" {
|
||||
* off the shell programs including paranoia.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
typedef signed8 B; /* signed 8-bit integer */
|
||||
typedef signed16 H; /* signed 16-bit integer */
|
||||
typedef signed32 W; /* signed 32-bit integer */
|
||||
typedef unsigned8 UB; /* unsigned 8-bit integer */
|
||||
typedef unsigned16 UH; /* unsigned 16-bit integer */
|
||||
typedef unsigned32 UW; /* unsigned 32-bit integer */
|
||||
#endif
|
||||
|
||||
typedef unsigned32 VW; /* unpredictable data type (32-bit size) */
|
||||
typedef unsigned16 VH; /* unpredictable data type (16-bit size) */
|
||||
|
||||
@@ -80,7 +80,7 @@ typedef Objects_Control ITRON_Objects_Control;
|
||||
#define _ITRON_Objects_Clarify_get_id_error( _the_information, _id ) \
|
||||
(((_id) < -4) ? E_OACV : /* attempt to access a "system object" */ \
|
||||
((_id) <= 0) ? E_ID : /* bogus index of 0 - -3 */ \
|
||||
((_id) <= (_the_information)->maximum) ? E_OBJ : /* object is in use */ \
|
||||
((_id) <= (_the_information)->maximum) ? E_NOEXS : /* does not exist */ \
|
||||
E_ID) /* simply a bad id */
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,18 @@ ER _ITRON_Delete_task(
|
||||
Thread_Control *the_thread
|
||||
);
|
||||
|
||||
/* XXX remove the need for this. Enable dispatch should not be hidden */
|
||||
|
||||
#define _ITRON_return_errorno( _errno ) \
|
||||
do { \
|
||||
_Thread_Enable_dispatch(); \
|
||||
return _errno; \
|
||||
} while (0);
|
||||
|
||||
|
||||
#ifndef __RTEMS_APPLICATION__
|
||||
#include <rtems/itron/task.inl>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -109,7 +109,13 @@ RTEMS_INLINE_ROUTINE Thread_Control *_ITRON_Task_Get (
|
||||
ID id,
|
||||
Objects_Locations *location
|
||||
)
|
||||
{
|
||||
{
|
||||
if ( id == 0 ) {
|
||||
_Thread_Disable_dispatch();
|
||||
*location = OBJECTS_LOCAL;
|
||||
return _Thread_Executing;
|
||||
}
|
||||
|
||||
return (Thread_Control *)
|
||||
_ITRON_Objects_Get( &_ITRON_Task_Information, id, location );
|
||||
}
|
||||
@@ -144,17 +150,29 @@ RTEMS_INLINE_ROUTINE boolean _ITRON_Task_Is_null (
|
||||
* _ITRON_tasks_Priority_to_Core
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE Priority_Control _ITRON_Task_Priority_to_Core(
|
||||
PRI _priority
|
||||
RTEMS_INLINE_ROUTINE _ITRON_Task_Priority_to_Core(
|
||||
PRI ITRON_priority
|
||||
)
|
||||
{
|
||||
return ((Priority_Control) (_priority));
|
||||
return (Priority_Control) ITRON_priority;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _ITRON_tasks_Core_to_Priority
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE _ITRON_Task_Core_to_Priority(
|
||||
Priority_Control core_priority
|
||||
)
|
||||
{
|
||||
return (PRI) core_priority;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ ER can_wup(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* XXX - FILL ME IN.
|
||||
*/
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,44 @@ ER chg_pri(
|
||||
PRI tskpri
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
Priority_Control new_priority;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
return -1;
|
||||
|
||||
if (( tskpri <= 0 ) || ( tskpri >= 256 ))
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ));
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
new_priority = _ITRON_Task_Priority_to_Core( tskpri );
|
||||
the_thread->real_priority = new_priority;
|
||||
|
||||
/*
|
||||
* XXX This is from the rtems side and I'm not sure what this is for.
|
||||
* XXX Is this check right or should change priority be called
|
||||
* regardless?
|
||||
*/
|
||||
|
||||
if ( the_thread->resource_count == 0 ||
|
||||
the_thread->current_priority > new_priority )
|
||||
_Thread_Change_priority( the_thread, new_priority, FALSE );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,28 +21,6 @@
|
||||
* cre_tsk - Create Task
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX - How do I return these errors ??? Do I have to validate the ID
|
||||
prior to calling the ID routine ??
|
||||
E_NOMEM Insufficient memory (Memory for control block and/or user stack
|
||||
cannot be allocated)
|
||||
E_ID Invalid ID Number (tskid was invalid or could not be used)
|
||||
E_RSATR Reserved attribute (tskatr was invalid or could not be used)
|
||||
E_OBJ Invalid object state (a task of the same ID already exists)
|
||||
E_OACV Object access violation (A tskid less than -4 was specified from
|
||||
a user task. This is implementation dependent.)
|
||||
E_PAR Parameter error (pk_ctsk, task, itskpri and/or stksz is invalid)
|
||||
EN_OBJNO An object number which could not be accessed on the target node
|
||||
is specified.
|
||||
EN_CTXID Specified an object on another node when the system call was
|
||||
issued from a task in dispatch disabled state or from a task-
|
||||
independent portion
|
||||
EN_PAR A value outside the range supported by the target node and/or
|
||||
transmission packet format was specified as a parameter (a value
|
||||
outside supported range was specified for exinf, tskatr, task,
|
||||
itskpri and/or stksz)
|
||||
*/
|
||||
|
||||
ER cre_tsk(
|
||||
ID tskid,
|
||||
T_CTSK *pk_ctsk
|
||||
@@ -59,19 +37,40 @@ ER cre_tsk(
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/*
|
||||
* Validate Parameters.
|
||||
*/
|
||||
|
||||
if ( pk_ctsk == NULL )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
if ((pk_ctsk->tskatr != TA_ASM ) &&
|
||||
(pk_ctsk->tskatr != TA_HLNG) &&
|
||||
(pk_ctsk->tskatr != TA_COP0) &&
|
||||
(pk_ctsk->tskatr != TA_COP1) &&
|
||||
(pk_ctsk->tskatr != TA_COP2) &&
|
||||
(pk_ctsk->tskatr != TA_COP3) &&
|
||||
(pk_ctsk->tskatr != TA_COP4) &&
|
||||
(pk_ctsk->tskatr != TA_COP5) &&
|
||||
(pk_ctsk->tskatr != TA_COP6) &&
|
||||
(pk_ctsk->tskatr != TA_COP7))
|
||||
_ITRON_return_errorno( E_RSATR );
|
||||
|
||||
if (( pk_ctsk->itskpri <= 0 ) || ( pk_ctsk->itskpri >= 256 ))
|
||||
if ( pk_ctsk->itskpri <= 0 )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
if ( pk_ctsk->task == NULL )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
if ( pk_ctsk->stksz < 0 )
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
/*
|
||||
* allocate the thread.
|
||||
*/
|
||||
|
||||
the_thread = _ITRON_Task_Allocate( tskid );
|
||||
if ( !the_thread ) {
|
||||
ena_dsp();
|
||||
return _ITRON_Task_Clarify_allocation_id_error( tskid );
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - FIX THE VARIABLES TO THE CORRECT VALUES!!!
|
||||
*/
|
||||
if ( !the_thread )
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_allocation_id_error( tskid ) );
|
||||
|
||||
/*
|
||||
* Initialize the core thread for this task.
|
||||
@@ -83,7 +82,7 @@ ER cre_tsk(
|
||||
the_thread,
|
||||
NULL,
|
||||
pk_ctsk->stksz,
|
||||
TRUE, /* XXX - All tasks FP ??? */
|
||||
TRUE, /* XXX - All tasks FP for now */
|
||||
core_priority,
|
||||
TRUE,
|
||||
THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE,
|
||||
@@ -94,22 +93,9 @@ ER cre_tsk(
|
||||
|
||||
if ( !status ) {
|
||||
_ITRON_Task_Free( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return -1;
|
||||
#if (0)
|
||||
/* XXX */
|
||||
#endif
|
||||
_ITRON_return_errorno( E_NOMEM );
|
||||
}
|
||||
|
||||
#if (0) /* XXX We have any thing else to set per API structure? */
|
||||
api = the_thread->API_Extensions[ THREAD_API_ITRON ];
|
||||
asr = &api->Signal;
|
||||
|
||||
asr->is_enabled = FALSE;
|
||||
|
||||
*id = the_thread->Object.id;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This insures we evaluate the process-wide signals pending when we
|
||||
* first run.
|
||||
@@ -125,3 +111,6 @@ ER cre_tsk(
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,16 +29,21 @@ ER del_tsk(
|
||||
Objects_Locations location;
|
||||
ER result;
|
||||
|
||||
/* XXX - Fix Documentation and error checking for this error on self */
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_Thread_Enable_dispatch();
|
||||
return _ITRON_Task_Clarify_get_id_error( tskid );
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
result = _ITRON_Delete_task( the_thread );
|
||||
|
||||
@@ -25,13 +25,13 @@ void exd_tsk( void )
|
||||
{
|
||||
Objects_Information *the_information;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
the_information = _Objects_Get_information( _Thread_Executing->Object.id );
|
||||
|
||||
/* This should never happen if _Thread_Get() works right */
|
||||
assert( the_information );
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
_Thread_Set_state( _Thread_Executing, STATES_DORMANT );
|
||||
_ITRON_Delete_task( _Thread_Executing );
|
||||
|
||||
|
||||
@@ -23,5 +23,10 @@
|
||||
|
||||
void ext_tsk( void )
|
||||
{
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
_Thread_Restart( _Thread_Executing, NULL, 0 );
|
||||
_Thread_Set_state( _Thread_Executing, STATES_DORMANT );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,32 @@ ER frsm_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Resume( the_thread, TRUE );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ ER get_tid(
|
||||
ID *p_tskid
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This does not support multiprocessing. The id handling will have
|
||||
* to be enhanced to support multiprocessing.
|
||||
*/
|
||||
|
||||
*p_tskid = _Objects_Get_index( _Thread_Executing->Object.id );
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,59 @@ ER ref_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
Priority_Control core_priority;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if (!pk_rtsk)
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
/*
|
||||
* The following are extended functions [level X ].
|
||||
* XXX - tskwait, wid, wupcnt, and tskatr are presently not implemented.
|
||||
*/
|
||||
|
||||
pk_rtsk->tskwait = 0;
|
||||
pk_rtsk->wid = 0;
|
||||
pk_rtsk->wupcnt = 0;
|
||||
pk_rtsk->suscnt = the_thread->suspend_count;
|
||||
pk_rtsk->tskatr = 0;
|
||||
pk_rtsk->task = the_thread->Start.entry_point;
|
||||
core_priority = the_thread->Start.initial_priority;
|
||||
pk_rtsk->itskpri = _ITRON_Task_Core_to_Priority( core_priority );
|
||||
pk_rtsk->stksz = the_thread->Start.Initial_stack.size;
|
||||
|
||||
/*
|
||||
* The following are required.
|
||||
*/
|
||||
|
||||
pk_rtsk->exinf = NULL; /* extended information */
|
||||
pk_rtsk->tskpri = _ITRON_Task_Core_to_Priority(the_thread->current_priority);
|
||||
pk_rtsk->tskstat = 0;
|
||||
|
||||
/*
|
||||
* Mask in the tskstat information
|
||||
* Convert the task state XXX double check this
|
||||
*/
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
pk_rtsk->tskstat |= TTS_RUN;
|
||||
if ((the_thread->current_state & STATES_READY) != 0)
|
||||
pk_rtsk->tskstat = TTS_RDY;
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
pk_rtsk->tskstat = TTS_DMT;
|
||||
if ((the_thread->current_state & STATES_SUSPENDED) != 0)
|
||||
pk_rtsk->tskstat = TTS_SUS;
|
||||
if ((the_thread->current_state & STATES_BLOCKED) != 0)
|
||||
pk_rtsk->tskstat = TTS_WAI;
|
||||
|
||||
return E_OK; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,30 @@ ER rel_wai(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_Thread_Enable_dispatch();
|
||||
return _ITRON_Task_Clarify_get_id_error( tskid );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* XXX - FILL ME IN.
|
||||
*/
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,26 @@ ER rot_rdq(
|
||||
PRI tskpri
|
||||
)
|
||||
{
|
||||
PRI priority;
|
||||
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/*
|
||||
* Yield of processor will rotate the queue for this processor.
|
||||
*/
|
||||
|
||||
if (( tskpri <= 0 ) || ( tskpri >= 256 ))
|
||||
_ITRON_return_errorno( E_PAR );
|
||||
|
||||
priority = _ITRON_Task_Core_to_Priority(_Thread_Executing->current_priority);
|
||||
if ( priority == tskpri )
|
||||
_Thread_Yield_processor();
|
||||
else {
|
||||
_Thread_Rotate_Ready_Queue( _ITRON_Task_Core_to_Priority( tskpri ) );
|
||||
}
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,31 @@ ER rsm_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if (_States_Is_dormant( the_thread->current_state ))
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Resume( the_thread, FALSE );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* slp_tsk - Sleep Task Sleep Task with Timeout
|
||||
* slp_tsk - Sleep Task
|
||||
*/
|
||||
|
||||
ER slp_tsk( void )
|
||||
|
||||
@@ -21,24 +21,6 @@
|
||||
* sta_tsk - Start Task
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX - How Do I know when these happen ???
|
||||
E_NOEXS Object does not exist (the task specified by tskid does not exist)
|
||||
E_OACV Object access violation (A tskid less than -4 was specified from
|
||||
a user task. This is implementation dependent.)
|
||||
E_OBJ Invalid object state (the target task is not in DORMANT state)
|
||||
EN_OBJNO An object number which could not be accessed on the target node
|
||||
is specified. XXX Should never get on a single processor??
|
||||
EN_CTXID Specified an object on another node when the system call was
|
||||
issued from a task in dispatch disabled state or from a task-
|
||||
independent portionXXX Should never get on a single processor??
|
||||
EN_PAR A value outside the range supported by the target node and/or
|
||||
transmission packet format was specified as a parameter (a value
|
||||
outside supported range was specified for stacd)
|
||||
XXX- What does _ITRON_Task_Get return on an invalid id and how do you know
|
||||
if it is E_ID, E_NOEXS, E_OACV
|
||||
*/
|
||||
|
||||
ER sta_tsk(
|
||||
ID tskid,
|
||||
INT stacd
|
||||
@@ -49,10 +31,16 @@ ER sta_tsk(
|
||||
boolean status;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
return E_ID; /* XXX */
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
status = _Thread_Start(
|
||||
@@ -63,14 +51,8 @@ ER sta_tsk(
|
||||
0 /* unused */
|
||||
);
|
||||
|
||||
/*
|
||||
* Wrong state XXX
|
||||
*/
|
||||
|
||||
if ( !status ) {
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OBJ;
|
||||
}
|
||||
if ( !status )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
|
||||
@@ -29,6 +29,33 @@ ER sus_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
return E_OK;
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
if (!the_thread)
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
switch ( location ) {
|
||||
case OBJECTS_REMOTE:
|
||||
case OBJECTS_ERROR:
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
_Thread_Suspend( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
return E_OBJ; /* XXX - Should never get here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -117,10 +117,8 @@ ER _ITRON_Delete_task(
|
||||
Objects_Information *the_information;
|
||||
|
||||
the_information = _Objects_Get_information( the_thread->Object.id );
|
||||
|
||||
if ( !the_information ) {
|
||||
return -1; /* XXX */
|
||||
/* This should never happen if _Thread_Get() works right */
|
||||
return E_OBJ; /* XXX - should never happen */
|
||||
}
|
||||
|
||||
_Thread_Close( the_information, the_thread );
|
||||
|
||||
@@ -18,13 +18,37 @@
|
||||
|
||||
|
||||
/*
|
||||
* ter_tsk - Terminate Other Task
|
||||
* ter_tsk - Terminate Other Task - Set State to DORMANT
|
||||
*/
|
||||
|
||||
ER ter_tsk(
|
||||
ID tskid
|
||||
)
|
||||
{
|
||||
register Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
the_thread = _ITRON_Task_Get( tskid, &location );
|
||||
|
||||
if ( !the_thread )
|
||||
_ITRON_return_errorno( _ITRON_Task_Clarify_get_id_error( tskid ) );
|
||||
|
||||
if ( the_thread == _Thread_Executing )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
if ( _States_Is_dormant( the_thread->current_state ) )
|
||||
_ITRON_return_errorno( E_OBJ );
|
||||
|
||||
_Thread_Restart( the_thread, NULL, 0 );
|
||||
_Thread_Set_state( the_thread, STATES_DORMANT );
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ rtems_status_code rtems_task_resume(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
if ( _States_Is_suspended( the_thread->current_state ) ) {
|
||||
_Thread_Resume( the_thread );
|
||||
_Thread_Resume( the_thread, TRUE );
|
||||
_Thread_Enable_dispatch();
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ rtems_status_code rtems_task_suspend(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
if ( !_States_Is_suspended( the_thread->current_state ) ) {
|
||||
_Thread_Set_state( the_thread, STATES_SUSPENDED );
|
||||
_Thread_Suspend( the_thread );
|
||||
_Thread_Enable_dispatch();
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -185,6 +185,7 @@ struct Thread_Control_struct {
|
||||
MP_packet_Prefix *receive_packet;
|
||||
#endif
|
||||
/****************** end of common block ********************/
|
||||
unsigned32 suspend_count;
|
||||
boolean is_global;
|
||||
boolean do_post_task_switch_extension;
|
||||
|
||||
@@ -552,6 +553,20 @@ void _Thread_Tickle_timeslice( void );
|
||||
|
||||
void _Thread_Yield_processor( void );
|
||||
|
||||
/*
|
||||
* _Thread_Rotate_Ready_Queue
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked to rotate the ready queue for the
|
||||
* given priority. It can be used to yeild the processor
|
||||
* by rotating the executing threads ready queue.
|
||||
*/
|
||||
|
||||
void _Thread_Rotate_Ready_Queue(
|
||||
Priority_Control priority
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Load_environment
|
||||
*
|
||||
@@ -623,12 +638,43 @@ void _Thread_Set_priority(
|
||||
Priority_Control new_priority
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Suspend
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine updates the related suspend fields in the_thread
|
||||
* control block to indicate the current nested level.
|
||||
*/
|
||||
|
||||
void _Thread_Suspend(
|
||||
Thread_Control *the_thread
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine updates the related suspend fields in the_thread
|
||||
* control block to indicate the current nested level. A force
|
||||
* parameter of TRUE will force a resume and clear the suspend count.
|
||||
*/
|
||||
|
||||
void _Thread_Resume(
|
||||
Thread_Control *the_thread,
|
||||
boolean force
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Evaluate_mode
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine XXX
|
||||
* This routine evaluates the current scheduling information for the
|
||||
* system and determines if a context switch is required. This
|
||||
* is usually called after changing an execution mode such as preemptability
|
||||
* for a thread.
|
||||
*/
|
||||
|
||||
boolean _Thread_Evaluate_mode( void );
|
||||
|
||||
@@ -82,24 +82,6 @@ RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing_also_the_heir( void )
|
||||
return ( _Thread_Executing == _Thread_Heir );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine clears the SUSPENDED state for the_thread. It performs
|
||||
* any necessary scheduling operations including the selection of
|
||||
* a new heir thread.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Resume (
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Thread_Clear_state( the_thread, STATES_SUSPENDED );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Unblock
|
||||
|
||||
@@ -53,15 +53,6 @@
|
||||
#define _Thread_Is_executing_also_the_heir() \
|
||||
( _Thread_Executing == _Thread_Heir )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Resume( _the_thread ) \
|
||||
_Thread_Clear_state( (_the_thread), STATES_SUSPENDED )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Unblock
|
||||
|
||||
@@ -153,6 +153,7 @@ boolean _Thread_Initialize(
|
||||
|
||||
the_thread->current_state = STATES_DORMANT;
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->suspend_count = 0;
|
||||
the_thread->real_priority = priority;
|
||||
the_thread->Start.initial_priority = priority;
|
||||
the_thread->ticks_executed = 0;
|
||||
|
||||
@@ -44,7 +44,8 @@ boolean _Thread_Restart(
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) ) {
|
||||
|
||||
_Thread_Set_transient( the_thread );
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->resource_count = 0;
|
||||
the_thread->suspend_count = 0;
|
||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||
|
||||
95
cpukit/score/src/threadresume.c
Normal file
95
cpukit/score/src/threadresume.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Resume
|
||||
*
|
||||
* This kernel routine clears the SUSPEND state if the suspend_count
|
||||
* drops below one. If the force parameter is set the suspend_count
|
||||
* is forced back to zero. The thread ready chain is adjusted if
|
||||
* necessary and the Heir thread is set accordingly.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_thread - pointer to thread control block
|
||||
* force - force the suspend count back to 0
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* priority map
|
||||
* select heir
|
||||
*/
|
||||
|
||||
|
||||
void _Thread_Resume(
|
||||
Thread_Control *the_thread,
|
||||
boolean force
|
||||
)
|
||||
{
|
||||
|
||||
ISR_Level level;
|
||||
States_Control current_state;
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
if ( force == TRUE )
|
||||
the_thread->suspend_count = 0;
|
||||
else
|
||||
the_thread->suspend_count--;
|
||||
|
||||
if ( the_thread->suspend_count > 0 ) {
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
current_state = the_thread->current_state;
|
||||
if ( current_state & STATES_SUSPENDED ) {
|
||||
current_state =
|
||||
the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state);
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
|
||||
_Priority_Add_to_bit_map( &the_thread->Priority_map );
|
||||
|
||||
_Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
|
||||
_Thread_Heir = the_thread;
|
||||
if ( _Thread_Executing->is_preemptible ||
|
||||
the_thread->current_priority == 0 )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
93
cpukit/score/src/threadrotatequeue.c
Normal file
93
cpukit/score/src/threadrotatequeue.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Rotate_Ready_Queue
|
||||
*
|
||||
* This kernel routine will rotate the ready queue.
|
||||
* remove the running THREAD from the ready chain
|
||||
* and place it immediatly at the rear of this chain. Reset timeslice
|
||||
* and yield the processor functions both use this routine, therefore if
|
||||
* reset is TRUE and this is the only thread on the chain then the
|
||||
* timeslice counter is reset. The heir THREAD will be updated if the
|
||||
* running is also the currently the heir.
|
||||
*
|
||||
* Input parameters:
|
||||
* Priority of the queue we wish to modify.
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* ready chain
|
||||
* select heir
|
||||
*/
|
||||
|
||||
void _Thread_Rotate_Ready_Queue(
|
||||
Priority_Control priority
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
Chain_Control *ready;
|
||||
Chain_Node *node;
|
||||
|
||||
ready = &_Thread_Ready_chain[ priority ];
|
||||
executing = _Thread_Executing;
|
||||
|
||||
if ( ready == executing->ready ) {
|
||||
_Thread_Yield_processor();
|
||||
return;
|
||||
}
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
if ( !_Chain_Is_empty( ready ) ) {
|
||||
if (!_Chain_Has_only_one_node( ready ) ) {
|
||||
node = _Chain_Get_first_unprotected( ready );
|
||||
_Chain_Append_unprotected( ready, node );
|
||||
}
|
||||
}
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( _Thread_Heir->ready == ready )
|
||||
_Thread_Heir = (Thread_Control *) ready->first;
|
||||
|
||||
if ( executing != _Thread_Heir )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
83
cpukit/score/src/threadsuspend.c
Normal file
83
cpukit/score/src/threadsuspend.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Thread Handler
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <rtems/score/context.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/threadq.h>
|
||||
#include <rtems/score/userext.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Suspend
|
||||
*
|
||||
* This kernel routine sets the SUSPEND state in the THREAD. The
|
||||
* THREAD chain and suspend count are adjusted if necessary.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_thread - pointer to thread control block
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* ready chain
|
||||
* select map
|
||||
*/
|
||||
|
||||
void _Thread_Suspend(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Chain_Control *ready;
|
||||
|
||||
ready = the_thread->ready;
|
||||
_ISR_Disable( level );
|
||||
the_thread->suspend_count++;
|
||||
if ( !_States_Is_ready( the_thread->current_state ) ) {
|
||||
the_thread->current_state =
|
||||
_States_Set( STATES_SUSPENDED, the_thread->current_state );
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
the_thread->current_state = STATES_SUSPENDED;
|
||||
|
||||
if ( _Chain_Has_only_one_node( ready ) ) {
|
||||
|
||||
_Chain_Initialize_empty( ready );
|
||||
_Priority_Remove_from_bit_map( &the_thread->Priority_map );
|
||||
|
||||
} else
|
||||
_Chain_Extract_unprotected( &the_thread->Object.Node );
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( _Thread_Is_heir( the_thread ) )
|
||||
_Thread_Calculate_heir();
|
||||
|
||||
if ( _Thread_Is_executing( the_thread ) )
|
||||
_Context_Switch_necessary = TRUE;
|
||||
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
Reference in New Issue
Block a user