Committed modifications from ITRON Task and Task Dependendent Synchronization

Working Group.  Included are tests.
This commit is contained in:
Joel Sherrill
1999-11-10 13:48:27 +00:00
parent dcc1f6b666
commit eb02f47b12
67 changed files with 1389 additions and 419 deletions

View File

@@ -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) */

View File

@@ -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 */

View File

@@ -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
}

View File

@@ -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 */

View 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 */
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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();
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 */
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 */
}

View File

@@ -19,7 +19,7 @@
/*
* slp_tsk - Sleep Task Sleep Task with Timeout
* slp_tsk - Sleep Task
*/
ER slp_tsk( void )

View File

@@ -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;

View File

@@ -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 */
}

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 \

View File

@@ -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 );

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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;

View File

@@ -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;

View 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 );
}

View 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 );
}

View 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 );
}

View File

@@ -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)

View File

@@ -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" );
}

View File

@@ -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)

View File

@@ -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) */

View File

@@ -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 */

View File

@@ -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
}

View File

@@ -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 */

View 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 */
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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();
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 */
}

View File

@@ -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 */
}

View File

@@ -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;
}

View File

@@ -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 */
}

View File

@@ -19,7 +19,7 @@
/*
* slp_tsk - Sleep Task Sleep Task with Timeout
* slp_tsk - Sleep Task
*/
ER slp_tsk( void )

View File

@@ -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;

View File

@@ -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 */
}

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View 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 );
}

View 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 );
}

View 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 );
}