summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-10 13:48:27 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-10 13:48:27 +0000
commiteb02f47b126b56091ffaeaad470a48e2ac6d57b5 (patch)
treed52c66ad2d1a1b60d4eecd873949aa07477f8b87
parentAdded support for ITRON tests. (diff)
downloadrtems-eb02f47b126b56091ffaeaad470a48e2ac6d57b5.tar.bz2
Committed modifications from ITRON Task and Task Dependendent Synchronization
Working Group. Included are tests.
Diffstat (limited to '')
-rw-r--r--c/src/exec/itron/include/itronsys/types.h2
-rw-r--r--c/src/exec/itron/include/rtems/itron/object.h2
-rw-r--r--c/src/exec/itron/include/rtems/itron/task.h11
-rw-r--r--c/src/exec/itron/inline/rtems/itron/task.inl28
-rw-r--r--c/src/exec/itron/src/can_wup.c21
-rw-r--r--c/src/exec/itron/src/chg_pri.c40
-rw-r--r--c/src/exec/itron/src/cre_tsk.c79
-rw-r--r--c/src/exec/itron/src/del_tsk.c15
-rw-r--r--c/src/exec/itron/src/exd_tsk.c4
-rw-r--r--c/src/exec/itron/src/ext_tsk.c5
-rw-r--r--c/src/exec/itron/src/frsm_tsk.c27
-rw-r--r--c/src/exec/itron/src/get_tid.c6
-rw-r--r--c/src/exec/itron/src/ref_tsk.c55
-rw-r--r--c/src/exec/itron/src/rel_wai.c25
-rw-r--r--c/src/exec/itron/src/rot_rdq.c20
-rw-r--r--c/src/exec/itron/src/rsm_tsk.c27
-rw-r--r--c/src/exec/itron/src/slp_tsk.c2
-rw-r--r--c/src/exec/itron/src/sta_tsk.c36
-rw-r--r--c/src/exec/itron/src/sus_tsk.c29
-rw-r--r--c/src/exec/itron/src/task.c4
-rw-r--r--c/src/exec/itron/src/ter_tsk.c26
-rw-r--r--c/src/exec/rtems/src/taskresume.c2
-rw-r--r--c/src/exec/rtems/src/tasksuspend.c2
-rw-r--r--c/src/exec/score/include/rtems/score/Makefile.in5
-rw-r--r--c/src/exec/score/include/rtems/score/thread.h48
-rw-r--r--c/src/exec/score/inline/rtems/score/thread.inl18
-rw-r--r--c/src/exec/score/macros/rtems/score/thread.inl9
-rw-r--r--c/src/exec/score/src/Makefile.in8
-rw-r--r--c/src/exec/score/src/threadinitialize.c1
-rw-r--r--c/src/exec/score/src/threadrestart.c3
-rw-r--r--c/src/exec/score/src/threadresume.c95
-rw-r--r--c/src/exec/score/src/threadrotatequeue.c93
-rw-r--r--c/src/exec/score/src/threadsuspend.c83
-rw-r--r--c/src/tests/itrontests/itrontask03/Makefile.in2
-rw-r--r--c/src/tests/itrontests/itrontask03/spinit.c152
-rw-r--r--configure.in5
-rw-r--r--cpukit/itron/include/itronsys/types.h2
-rw-r--r--cpukit/itron/include/rtems/itron/object.h2
-rw-r--r--cpukit/itron/include/rtems/itron/task.h11
-rw-r--r--cpukit/itron/inline/rtems/itron/task.inl28
-rw-r--r--cpukit/itron/src/can_wup.c21
-rw-r--r--cpukit/itron/src/chg_pri.c40
-rw-r--r--cpukit/itron/src/cre_tsk.c79
-rw-r--r--cpukit/itron/src/del_tsk.c15
-rw-r--r--cpukit/itron/src/exd_tsk.c4
-rw-r--r--cpukit/itron/src/ext_tsk.c5
-rw-r--r--cpukit/itron/src/frsm_tsk.c27
-rw-r--r--cpukit/itron/src/get_tid.c6
-rw-r--r--cpukit/itron/src/ref_tsk.c55
-rw-r--r--cpukit/itron/src/rel_wai.c25
-rw-r--r--cpukit/itron/src/rot_rdq.c20
-rw-r--r--cpukit/itron/src/rsm_tsk.c27
-rw-r--r--cpukit/itron/src/slp_tsk.c2
-rw-r--r--cpukit/itron/src/sta_tsk.c36
-rw-r--r--cpukit/itron/src/sus_tsk.c29
-rw-r--r--cpukit/itron/src/task.c4
-rw-r--r--cpukit/itron/src/ter_tsk.c26
-rw-r--r--cpukit/rtems/src/taskresume.c2
-rw-r--r--cpukit/rtems/src/tasksuspend.c2
-rw-r--r--cpukit/score/include/rtems/score/thread.h48
-rw-r--r--cpukit/score/inline/rtems/score/thread.inl18
-rw-r--r--cpukit/score/macros/rtems/score/thread.inl9
-rw-r--r--cpukit/score/src/threadinitialize.c1
-rw-r--r--cpukit/score/src/threadrestart.c3
-rw-r--r--cpukit/score/src/threadresume.c95
-rw-r--r--cpukit/score/src/threadrotatequeue.c93
-rw-r--r--cpukit/score/src/threadsuspend.c83
67 files changed, 1389 insertions, 419 deletions
diff --git a/c/src/exec/itron/include/itronsys/types.h b/c/src/exec/itron/include/itronsys/types.h
index c9dc8db40e..80cb31f3b8 100644
--- a/c/src/exec/itron/include/itronsys/types.h
+++ b/c/src/exec/itron/include/itronsys/types.h
@@ -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) */
diff --git a/c/src/exec/itron/include/rtems/itron/object.h b/c/src/exec/itron/include/rtems/itron/object.h
index 71bc9ed6d1..919baffd9e 100644
--- a/c/src/exec/itron/include/rtems/itron/object.h
+++ b/c/src/exec/itron/include/rtems/itron/object.h
@@ -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 */
diff --git a/c/src/exec/itron/include/rtems/itron/task.h b/c/src/exec/itron/include/rtems/itron/task.h
index fffcc16d82..5d52d632f5 100644
--- a/c/src/exec/itron/include/rtems/itron/task.h
+++ b/c/src/exec/itron/include/rtems/itron/task.h
@@ -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
}
diff --git a/c/src/exec/itron/inline/rtems/itron/task.inl b/c/src/exec/itron/inline/rtems/itron/task.inl
index 1833fee84a..834e47b0c9 100644
--- a/c/src/exec/itron/inline/rtems/itron/task.inl
+++ b/c/src/exec/itron/inline/rtems/itron/task.inl
@@ -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) ITRON_priority;
+}
+
+/*PAGE
+ *
+ * _ITRON_tasks_Core_to_Priority
+ */
+
+RTEMS_INLINE_ROUTINE _ITRON_Task_Core_to_Priority(
+ Priority_Control core_priority
)
{
- return ((Priority_Control) (_priority));
+ return (PRI) core_priority;
}
+
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */
-
diff --git a/c/src/exec/itron/src/can_wup.c b/c/src/exec/itron/src/can_wup.c
index d75d379de9..b7442d1392 100644
--- a/c/src/exec/itron/src/can_wup.c
+++ b/c/src/exec/itron/src/can_wup.c
@@ -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 */
}
diff --git a/c/src/exec/itron/src/chg_pri.c b/c/src/exec/itron/src/chg_pri.c
index b2d42905e5..412bab054e 100644
--- a/c/src/exec/itron/src/chg_pri.c
+++ b/c/src/exec/itron/src/chg_pri.c
@@ -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 */
}
+
diff --git a/c/src/exec/itron/src/cre_tsk.c b/c/src/exec/itron/src/cre_tsk.c
index 76bcd75eda..f4e8e605fc 100644
--- a/c/src/exec/itron/src/cre_tsk.c
+++ b/c/src/exec/itron/src/cre_tsk.c
@@ -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
@@ -60,18 +38,39 @@ 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;
}
+
+
+
diff --git a/c/src/exec/itron/src/del_tsk.c b/c/src/exec/itron/src/del_tsk.c
index 5230acddca..4514eb6348 100644
--- a/c/src/exec/itron/src/del_tsk.c
+++ b/c/src/exec/itron/src/del_tsk.c
@@ -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 );
diff --git a/c/src/exec/itron/src/exd_tsk.c b/c/src/exec/itron/src/exd_tsk.c
index c2b86f3126..51c0eb04c5 100644
--- a/c/src/exec/itron/src/exd_tsk.c
+++ b/c/src/exec/itron/src/exd_tsk.c
@@ -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 );
diff --git a/c/src/exec/itron/src/ext_tsk.c b/c/src/exec/itron/src/ext_tsk.c
index a8a3b0ec23..d3f13939f1 100644
--- a/c/src/exec/itron/src/ext_tsk.c
+++ b/c/src/exec/itron/src/ext_tsk.c
@@ -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();
}
diff --git a/c/src/exec/itron/src/frsm_tsk.c b/c/src/exec/itron/src/frsm_tsk.c
index 8fe5e9e6fc..2840061dd6 100644
--- a/c/src/exec/itron/src/frsm_tsk.c
+++ b/c/src/exec/itron/src/frsm_tsk.c
@@ -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 */
+
}
diff --git a/c/src/exec/itron/src/get_tid.c b/c/src/exec/itron/src/get_tid.c
index 1c5175052a..7904e3e167 100644
--- a/c/src/exec/itron/src/get_tid.c
+++ b/c/src/exec/itron/src/get_tid.c
@@ -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;
}
diff --git a/c/src/exec/itron/src/ref_tsk.c b/c/src/exec/itron/src/ref_tsk.c
index 50ce76e8ed..2c6ad11709 100644
--- a/c/src/exec/itron/src/ref_tsk.c
+++ b/c/src/exec/itron/src/ref_tsk.c
@@ -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 */
}
+
+
+
diff --git a/c/src/exec/itron/src/rel_wai.c b/c/src/exec/itron/src/rel_wai.c
index 390433ec0c..81d7e6dc94 100644
--- a/c/src/exec/itron/src/rel_wai.c
+++ b/c/src/exec/itron/src/rel_wai.c
@@ -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 */
}
+
diff --git a/c/src/exec/itron/src/rot_rdq.c b/c/src/exec/itron/src/rot_rdq.c
index b329313946..ac6d89d55f 100644
--- a/c/src/exec/itron/src/rot_rdq.c
+++ b/c/src/exec/itron/src/rot_rdq.c
@@ -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;
}
diff --git a/c/src/exec/itron/src/rsm_tsk.c b/c/src/exec/itron/src/rsm_tsk.c
index a19842f8da..81be3446eb 100644
--- a/c/src/exec/itron/src/rsm_tsk.c
+++ b/c/src/exec/itron/src/rsm_tsk.c
@@ -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 */
}
diff --git a/c/src/exec/itron/src/slp_tsk.c b/c/src/exec/itron/src/slp_tsk.c
index 00562dda92..b8c84c9808 100644
--- a/c/src/exec/itron/src/slp_tsk.c
+++ b/c/src/exec/itron/src/slp_tsk.c
@@ -19,7 +19,7 @@
/*
- * slp_tsk - Sleep Task Sleep Task with Timeout
+ * slp_tsk - Sleep Task
*/
ER slp_tsk( void )
diff --git a/c/src/exec/itron/src/sta_tsk.c b/c/src/exec/itron/src/sta_tsk.c
index 91a6586c0e..73cc49e36b 100644
--- a/c/src/exec/itron/src/sta_tsk.c
+++ b/c/src/exec/itron/src/sta_tsk.c
@@ -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;
diff --git a/c/src/exec/itron/src/sus_tsk.c b/c/src/exec/itron/src/sus_tsk.c
index f4a5d5b851..12ef07ff7b 100644
--- a/c/src/exec/itron/src/sus_tsk.c
+++ b/c/src/exec/itron/src/sus_tsk.c
@@ -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 */
}
+
+
+
+
+
+
diff --git a/c/src/exec/itron/src/task.c b/c/src/exec/itron/src/task.c
index f646b29d49..c4e785a4bb 100644
--- a/c/src/exec/itron/src/task.c
+++ b/c/src/exec/itron/src/task.c
@@ -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 );
diff --git a/c/src/exec/itron/src/ter_tsk.c b/c/src/exec/itron/src/ter_tsk.c
index c0d05c1fec..070cfcee25 100644
--- a/c/src/exec/itron/src/ter_tsk.c
+++ b/c/src/exec/itron/src/ter_tsk.c
@@ -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;
}
+
+
+
+
+
+
diff --git a/c/src/exec/rtems/src/taskresume.c b/c/src/exec/rtems/src/taskresume.c
index 70c2051eaf..92360db43b 100644
--- a/c/src/exec/rtems/src/taskresume.c
+++ b/c/src/exec/rtems/src/taskresume.c
@@ -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;
}
diff --git a/c/src/exec/rtems/src/tasksuspend.c b/c/src/exec/rtems/src/tasksuspend.c
index c9635b0ff3..04fafcbea9 100644
--- a/c/src/exec/rtems/src/tasksuspend.c
+++ b/c/src/exec/rtems/src/tasksuspend.c
@@ -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;
}
diff --git a/c/src/exec/score/include/rtems/score/Makefile.in b/c/src/exec/score/include/rtems/score/Makefile.in
index 7dc33b70a7..42e8a8a055 100644
--- a/c/src/exec/score/include/rtems/score/Makefile.in
+++ b/c/src/exec/score/include/rtems/score/Makefile.in
@@ -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 \
diff --git a/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h
index 26452bffbe..bfc42b6fad 100644
--- a/c/src/exec/score/include/rtems/score/thread.h
+++ b/c/src/exec/score/include/rtems/score/thread.h
@@ -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
*
@@ -624,11 +639,42 @@ void _Thread_Set_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 );
diff --git a/c/src/exec/score/inline/rtems/score/thread.inl b/c/src/exec/score/inline/rtems/score/thread.inl
index eef4532c07..650439e8e6 100644
--- a/c/src/exec/score/inline/rtems/score/thread.inl
+++ b/c/src/exec/score/inline/rtems/score/thread.inl
@@ -84,24 +84,6 @@ RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing_also_the_heir( void )
/*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
*
* DESCRIPTION:
diff --git a/c/src/exec/score/macros/rtems/score/thread.inl b/c/src/exec/score/macros/rtems/score/thread.inl
index 96761143b8..415bb0fb8d 100644
--- a/c/src/exec/score/macros/rtems/score/thread.inl
+++ b/c/src/exec/score/macros/rtems/score/thread.inl
@@ -55,15 +55,6 @@
/*PAGE
*
- * _Thread_Resume
- *
- */
-
-#define _Thread_Resume( _the_thread ) \
- _Thread_Clear_state( (_the_thread), STATES_SUSPENDED )
-
-/*PAGE
- *
* _Thread_Unblock
*
*/
diff --git a/c/src/exec/score/src/Makefile.in b/c/src/exec/score/src/Makefile.in
index 28ad2ef6a3..99cce9fa76 100644
--- a/c/src/exec/score/src/Makefile.in
+++ b/c/src/exec/score/src/Makefile.in
@@ -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 \
diff --git a/c/src/exec/score/src/threadinitialize.c b/c/src/exec/score/src/threadinitialize.c
index 28cfa324bc..f294d865bf 100644
--- a/c/src/exec/score/src/threadinitialize.c
+++ b/c/src/exec/score/src/threadinitialize.c
@@ -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;
diff --git a/c/src/exec/score/src/threadrestart.c b/c/src/exec/score/src/threadrestart.c
index 7419514a4f..229dbe2d94 100644
--- a/c/src/exec/score/src/threadrestart.c
+++ b/c/src/exec/score/src/threadrestart.c
@@ -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;
diff --git a/c/src/exec/score/src/threadresume.c b/c/src/exec/score/src/threadresume.c
new file mode 100644
index 0000000000..067dc59610
--- /dev/null
+++ b/c/src/exec/score/src/threadresume.c
@@ -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 );
+}
diff --git a/c/src/exec/score/src/threadrotatequeue.c b/c/src/exec/score/src/threadrotatequeue.c
new file mode 100644
index 0000000000..f7ee9c12f5
--- /dev/null
+++ b/c/src/exec/score/src/threadrotatequeue.c
@@ -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 );
+}
+
+
+
+
+
+
diff --git a/c/src/exec/score/src/threadsuspend.c b/c/src/exec/score/src/threadsuspend.c
new file mode 100644
index 0000000000..82363054e5
--- /dev/null
+++ b/c/src/exec/score/src/threadsuspend.c
@@ -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 );
+}
diff --git a/c/src/tests/itrontests/itrontask03/Makefile.in b/c/src/tests/itrontests/itrontask03/Makefile.in
index 0435f04407..71c674f002 100644
--- a/c/src/tests/itrontests/itrontask03/Makefile.in
+++ b/c/src/tests/itrontests/itrontask03/Makefile.in
@@ -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)
diff --git a/c/src/tests/itrontests/itrontask03/spinit.c b/c/src/tests/itrontests/itrontask03/spinit.c
deleted file mode 100644
index dda2f9661c..0000000000
--- a/c/src/tests/itrontests/itrontask03/spinit.c
+++ /dev/null
@@ -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" );
-}
diff --git a/configure.in b/configure.in
index b202dde4f3..b2ed3269c0 100644
--- a/configure.in
+++ b/configure.in
@@ -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)
diff --git a/cpukit/itron/include/itronsys/types.h b/cpukit/itron/include/itronsys/types.h
index c9dc8db40e..80cb31f3b8 100644
--- a/cpukit/itron/include/itronsys/types.h
+++ b/cpukit/itron/include/itronsys/types.h
@@ -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) */
diff --git a/cpukit/itron/include/rtems/itron/object.h b/cpukit/itron/include/rtems/itron/object.h
index 71bc9ed6d1..919baffd9e 100644
--- a/cpukit/itron/include/rtems/itron/object.h
+++ b/cpukit/itron/include/rtems/itron/object.h
@@ -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 */
diff --git a/cpukit/itron/include/rtems/itron/task.h b/cpukit/itron/include/rtems/itron/task.h
index fffcc16d82..5d52d632f5 100644
--- a/cpukit/itron/include/rtems/itron/task.h
+++ b/cpukit/itron/include/rtems/itron/task.h
@@ -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
}
diff --git a/cpukit/itron/inline/rtems/itron/task.inl b/cpukit/itron/inline/rtems/itron/task.inl
index 1833fee84a..834e47b0c9 100644
--- a/cpukit/itron/inline/rtems/itron/task.inl
+++ b/cpukit/itron/inline/rtems/itron/task.inl
@@ -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) ITRON_priority;
+}
+
+/*PAGE
+ *
+ * _ITRON_tasks_Core_to_Priority
+ */
+
+RTEMS_INLINE_ROUTINE _ITRON_Task_Core_to_Priority(
+ Priority_Control core_priority
)
{
- return ((Priority_Control) (_priority));
+ return (PRI) core_priority;
}
+
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */
-
diff --git a/cpukit/itron/src/can_wup.c b/cpukit/itron/src/can_wup.c
index d75d379de9..b7442d1392 100644
--- a/cpukit/itron/src/can_wup.c
+++ b/cpukit/itron/src/can_wup.c
@@ -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 */
}
diff --git a/cpukit/itron/src/chg_pri.c b/cpukit/itron/src/chg_pri.c
index b2d42905e5..412bab054e 100644
--- a/cpukit/itron/src/chg_pri.c
+++ b/cpukit/itron/src/chg_pri.c
@@ -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 */
}
+
diff --git a/cpukit/itron/src/cre_tsk.c b/cpukit/itron/src/cre_tsk.c
index 76bcd75eda..f4e8e605fc 100644
--- a/cpukit/itron/src/cre_tsk.c
+++ b/cpukit/itron/src/cre_tsk.c
@@ -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
@@ -60,18 +38,39 @@ 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;
}
+
+
+
diff --git a/cpukit/itron/src/del_tsk.c b/cpukit/itron/src/del_tsk.c
index 5230acddca..4514eb6348 100644
--- a/cpukit/itron/src/del_tsk.c
+++ b/cpukit/itron/src/del_tsk.c
@@ -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 );
diff --git a/cpukit/itron/src/exd_tsk.c b/cpukit/itron/src/exd_tsk.c
index c2b86f3126..51c0eb04c5 100644
--- a/cpukit/itron/src/exd_tsk.c
+++ b/cpukit/itron/src/exd_tsk.c
@@ -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 );
diff --git a/cpukit/itron/src/ext_tsk.c b/cpukit/itron/src/ext_tsk.c
index a8a3b0ec23..d3f13939f1 100644
--- a/cpukit/itron/src/ext_tsk.c
+++ b/cpukit/itron/src/ext_tsk.c
@@ -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();
}
diff --git a/cpukit/itron/src/frsm_tsk.c b/cpukit/itron/src/frsm_tsk.c
index 8fe5e9e6fc..2840061dd6 100644
--- a/cpukit/itron/src/frsm_tsk.c
+++ b/cpukit/itron/src/frsm_tsk.c
@@ -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 */
+
}
diff --git a/cpukit/itron/src/get_tid.c b/cpukit/itron/src/get_tid.c
index 1c5175052a..7904e3e167 100644
--- a/cpukit/itron/src/get_tid.c
+++ b/cpukit/itron/src/get_tid.c
@@ -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;
}
diff --git a/cpukit/itron/src/ref_tsk.c b/cpukit/itron/src/ref_tsk.c
index 50ce76e8ed..2c6ad11709 100644
--- a/cpukit/itron/src/ref_tsk.c
+++ b/cpukit/itron/src/ref_tsk.c
@@ -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 */
}
+
+
+
diff --git a/cpukit/itron/src/rel_wai.c b/cpukit/itron/src/rel_wai.c
index 390433ec0c..81d7e6dc94 100644
--- a/cpukit/itron/src/rel_wai.c
+++ b/cpukit/itron/src/rel_wai.c
@@ -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 */
}
+
diff --git a/cpukit/itron/src/rot_rdq.c b/cpukit/itron/src/rot_rdq.c
index b329313946..ac6d89d55f 100644
--- a/cpukit/itron/src/rot_rdq.c
+++ b/cpukit/itron/src/rot_rdq.c
@@ -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;
}
diff --git a/cpukit/itron/src/rsm_tsk.c b/cpukit/itron/src/rsm_tsk.c
index a19842f8da..81be3446eb 100644
--- a/cpukit/itron/src/rsm_tsk.c
+++ b/cpukit/itron/src/rsm_tsk.c
@@ -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 */
}
diff --git a/cpukit/itron/src/slp_tsk.c b/cpukit/itron/src/slp_tsk.c
index 00562dda92..b8c84c9808 100644
--- a/cpukit/itron/src/slp_tsk.c
+++ b/cpukit/itron/src/slp_tsk.c
@@ -19,7 +19,7 @@
/*
- * slp_tsk - Sleep Task Sleep Task with Timeout
+ * slp_tsk - Sleep Task
*/
ER slp_tsk( void )
diff --git a/cpukit/itron/src/sta_tsk.c b/cpukit/itron/src/sta_tsk.c
index 91a6586c0e..73cc49e36b 100644
--- a/cpukit/itron/src/sta_tsk.c
+++ b/cpukit/itron/src/sta_tsk.c
@@ -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;
diff --git a/cpukit/itron/src/sus_tsk.c b/cpukit/itron/src/sus_tsk.c
index f4a5d5b851..12ef07ff7b 100644
--- a/cpukit/itron/src/sus_tsk.c
+++ b/cpukit/itron/src/sus_tsk.c
@@ -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 */
}
+
+
+
+
+
+
diff --git a/cpukit/itron/src/task.c b/cpukit/itron/src/task.c
index f646b29d49..c4e785a4bb 100644
--- a/cpukit/itron/src/task.c
+++ b/cpukit/itron/src/task.c
@@ -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 );
diff --git a/cpukit/itron/src/ter_tsk.c b/cpukit/itron/src/ter_tsk.c
index c0d05c1fec..070cfcee25 100644
--- a/cpukit/itron/src/ter_tsk.c
+++ b/cpukit/itron/src/ter_tsk.c
@@ -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;
}
+
+
+
+
+
+
diff --git a/cpukit/rtems/src/taskresume.c b/cpukit/rtems/src/taskresume.c
index 70c2051eaf..92360db43b 100644
--- a/cpukit/rtems/src/taskresume.c
+++ b/cpukit/rtems/src/taskresume.c
@@ -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;
}
diff --git a/cpukit/rtems/src/tasksuspend.c b/cpukit/rtems/src/tasksuspend.c
index c9635b0ff3..04fafcbea9 100644
--- a/cpukit/rtems/src/tasksuspend.c
+++ b/cpukit/rtems/src/tasksuspend.c
@@ -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;
}
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 26452bffbe..bfc42b6fad 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -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
*
@@ -624,11 +639,42 @@ void _Thread_Set_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 );
diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl
index eef4532c07..650439e8e6 100644
--- a/cpukit/score/inline/rtems/score/thread.inl
+++ b/cpukit/score/inline/rtems/score/thread.inl
@@ -84,24 +84,6 @@ RTEMS_INLINE_ROUTINE boolean _Thread_Is_executing_also_the_heir( void )
/*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
*
* DESCRIPTION:
diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl
index 96761143b8..415bb0fb8d 100644
--- a/cpukit/score/macros/rtems/score/thread.inl
+++ b/cpukit/score/macros/rtems/score/thread.inl
@@ -55,15 +55,6 @@
/*PAGE
*
- * _Thread_Resume
- *
- */
-
-#define _Thread_Resume( _the_thread ) \
- _Thread_Clear_state( (_the_thread), STATES_SUSPENDED )
-
-/*PAGE
- *
* _Thread_Unblock
*
*/
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 28cfa324bc..f294d865bf 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -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;
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 7419514a4f..229dbe2d94 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -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;
diff --git a/cpukit/score/src/threadresume.c b/cpukit/score/src/threadresume.c
new file mode 100644
index 0000000000..067dc59610
--- /dev/null
+++ b/cpukit/score/src/threadresume.c
@@ -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 );
+}
diff --git a/cpukit/score/src/threadrotatequeue.c b/cpukit/score/src/threadrotatequeue.c
new file mode 100644
index 0000000000..f7ee9c12f5
--- /dev/null
+++ b/cpukit/score/src/threadrotatequeue.c
@@ -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 );
+}
+
+
+
+
+
+
diff --git a/cpukit/score/src/threadsuspend.c b/cpukit/score/src/threadsuspend.c
new file mode 100644
index 0000000000..82363054e5
--- /dev/null
+++ b/cpukit/score/src/threadsuspend.c
@@ -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 );
+}