summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-02-28 16:15:35 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-02-28 16:15:35 +0000
commit5088d978385ce6d28db1731aab57b23ca1f6e9cc (patch)
tree2e061c7ff3c5287ac53f2945421425209cb2c33e /cpukit
parent2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-5088d978385ce6d28db1731aab57b23ca1f6e9cc.tar.bz2
2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com>
* itron/include/rtems/itron/task.h, itron/src/cre_tsk.c, posix/src/pthreadcreate.c, rtems/src/taskcreate.c, rtems/src/taskdelete.c, rtems/src/timerserver.c, score/src/threadclose.c, score/src/threadcreateidle.c, score/src/threadinitialize.c: Switch task create and delete operations to using API Allocator Mutex. This moves almost all uses of the RTEMS Workspace from dispatching disabled to mutex protected which should improve deterministic behavior. The implementation was carefully done to allow task create and delete extensions to invoke more services. In particular, a task delete extension should be able to do mutex and file operations.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/ChangeLog14
-rw-r--r--cpukit/itron/include/rtems/itron/task.h6
-rw-r--r--cpukit/itron/src/cre_tsk.c20
-rw-r--r--cpukit/posix/src/pthreadcreate.c19
-rw-r--r--cpukit/rtems/src/taskcreate.c16
-rw-r--r--cpukit/rtems/src/taskdelete.c6
-rw-r--r--cpukit/rtems/src/timerserver.c55
-rw-r--r--cpukit/score/src/threadclose.c32
-rw-r--r--cpukit/score/src/threadcreateidle.c11
-rw-r--r--cpukit/score/src/threadinitialize.c12
10 files changed, 133 insertions, 58 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index 42eeae108e..fc2f77746b 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,5 +1,19 @@
2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com>
+ * itron/include/rtems/itron/task.h, itron/src/cre_tsk.c,
+ posix/src/pthreadcreate.c, rtems/src/taskcreate.c,
+ rtems/src/taskdelete.c, rtems/src/timerserver.c,
+ score/src/threadclose.c, score/src/threadcreateidle.c,
+ score/src/threadinitialize.c: Switch task create and delete
+ operations to using API Allocator Mutex. This moves almost all uses
+ of the RTEMS Workspace from dispatching disabled to mutex protected
+ which should improve deterministic behavior. The implementation was
+ carefully done to allow task create and delete extensions to invoke
+ more services. In particular, a task delete extension should be able
+ to do mutex and file operations.
+
+2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com>
+
* libmisc/Makefile.am: Turn on NFS mount support when networking is
enabled.
diff --git a/cpukit/itron/include/rtems/itron/task.h b/cpukit/itron/include/rtems/itron/task.h
index e7ad311b29..e136c5719f 100644
--- a/cpukit/itron/include/rtems/itron/task.h
+++ b/cpukit/itron/include/rtems/itron/task.h
@@ -3,7 +3,7 @@
*/
/*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -84,7 +84,9 @@ ER _ITRON_Delete_task(
Thread_Control *the_thread
);
-/* XXX remove the need for this. Enable dispatch should not be hidden */
+/*
+ * Return a status code and enable dispatching
+ */
#define _ITRON_return_errorno( _errno ) \
do { \
diff --git a/cpukit/itron/src/cre_tsk.c b/cpukit/itron/src/cre_tsk.c
index 5ae87c1675..6c2047303a 100644
--- a/cpukit/itron/src/cre_tsk.c
+++ b/cpukit/itron/src/cre_tsk.c
@@ -1,5 +1,5 @@
/*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -20,6 +20,7 @@
#include <rtems/score/wkspace.h>
#include <rtems/score/apiext.h>
#include <rtems/score/sysstate.h>
+#include <rtems/score/apimutex.h>
#include <rtems/itron/task.h>
@@ -65,18 +66,19 @@ ER cre_tsk(
return E_PAR;
/*
- * Disable dispatching.
+ * Lock the allocator mutex for protection
*/
-
- _Thread_Disable_dispatch();
+ _RTEMS_Lock_allocator();
/*
* allocate the thread.
*/
the_thread = _ITRON_Task_Allocate( tskid );
- if ( !the_thread )
- _ITRON_return_errorno( _ITRON_Task_Clarify_allocation_id_error( tskid ) );
+ if ( !the_thread ) {
+ _RTEMS_Unlock_allocator();
+ return _ITRON_Task_Clarify_allocation_id_error( tskid );
+ }
/*
* Initialize the core thread for this task.
@@ -104,7 +106,8 @@ ER cre_tsk(
if ( !status ) {
_ITRON_Task_Free( the_thread );
- _ITRON_return_errorno( E_NOMEM );
+ _RTEMS_Unlock_allocator();
+ return E_NOMEM;
}
/*
@@ -118,5 +121,6 @@ ER cre_tsk(
the_thread->Start.entry_point = (Thread_Entry) pk_ctsk->task;
- _ITRON_return_errorno( E_OK );
+ _RTEMS_Unlock_allocator();
+ return E_OK;
}
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index e6bd5bc549..6eeda2da14 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -2,7 +2,7 @@
* 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
*/
-/* COPYRIGHT (c) 1989-2007.
+/* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -24,6 +24,7 @@
#include <rtems/posix/pthread.h>
#include <rtems/posix/priority.h>
#include <rtems/posix/time.h>
+#include <rtems/score/apimutex.h>
int pthread_create(
pthread_t *thread,
@@ -157,10 +158,9 @@ int pthread_create(
#endif
/*
- * Disable dispatch for protection
+ * Lock the allocator mutex for protection
*/
-
- _Thread_Disable_dispatch();
+ _RTEMS_Lock_allocator();
/*
* Allocate the thread control block.
@@ -171,7 +171,7 @@ int pthread_create(
the_thread = _POSIX_Threads_Allocate();
if ( !the_thread ) {
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return EAGAIN;
}
@@ -196,7 +196,7 @@ int pthread_create(
if ( !status ) {
_POSIX_Threads_Free( the_thread );
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return EAGAIN;
}
@@ -249,7 +249,7 @@ int pthread_create(
if ( !status ) {
_POSIX_Threads_Free( the_thread );
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return EINVAL;
}
@@ -259,7 +259,6 @@ int pthread_create(
*thread = the_thread->Object.id;
- _Thread_Enable_dispatch();
-
- return 0;
+ _RTEMS_Unlock_allocator();
+ return 0;
}
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
index 99e6628c92..38d924ad39 100644
--- a/cpukit/rtems/src/taskcreate.c
+++ b/cpukit/rtems/src/taskcreate.c
@@ -2,7 +2,7 @@
* RTEMS Task Manager
*
*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -31,6 +31,7 @@
#include <rtems/score/wkspace.h>
#include <rtems/score/apiext.h>
#include <rtems/score/sysstate.h>
+#include <rtems/score/apimutex.h>
/*PAGE
*
@@ -133,10 +134,9 @@ rtems_status_code rtems_task_create(
*/
/*
- * Disable dispatch for protection
+ * Lock the allocator mutex for protection
*/
-
- _Thread_Disable_dispatch();
+ _RTEMS_Lock_allocator();
/*
* Allocate the thread control block and -- if the task is global --
@@ -151,7 +151,7 @@ rtems_status_code rtems_task_create(
the_thread = _RTEMS_tasks_Allocate();
if ( !the_thread ) {
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return RTEMS_TOO_MANY;
}
@@ -161,7 +161,7 @@ rtems_status_code rtems_task_create(
if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
_RTEMS_tasks_Free( the_thread );
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return RTEMS_TOO_MANY;
}
}
@@ -193,7 +193,7 @@ rtems_status_code rtems_task_create(
_Objects_MP_Free_global_object( the_global_object );
#endif
_RTEMS_tasks_Free( the_thread );
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return RTEMS_UNSATISFIED;
}
@@ -224,6 +224,6 @@ rtems_status_code rtems_task_create(
}
#endif
- _Thread_Enable_dispatch();
+ _RTEMS_Unlock_allocator();
return RTEMS_SUCCESSFUL;
}
diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c
index 890596866b..c7b1edb60c 100644
--- a/cpukit/rtems/src/taskdelete.c
+++ b/cpukit/rtems/src/taskdelete.c
@@ -31,6 +31,7 @@
#include <rtems/score/wkspace.h>
#include <rtems/score/apiext.h>
#include <rtems/score/sysstate.h>
+#include <rtems/score/apimutex.h>
/*PAGE
*
@@ -58,6 +59,8 @@ rtems_status_code rtems_task_delete(
Objects_Locations location;
Objects_Information *the_information;
+ _RTEMS_Lock_allocator();
+
the_thread = _Thread_Get( id, &location );
switch ( location ) {
@@ -89,11 +92,13 @@ rtems_status_code rtems_task_delete(
}
#endif
+ _RTEMS_Unlock_allocator();
_Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL;
#if defined(RTEMS_MULTIPROCESSING)
case OBJECTS_REMOTE:
+ _RTEMS_Unlock_allocator();
_Thread_Dispatch();
return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
#endif
@@ -102,5 +107,6 @@ rtems_status_code rtems_task_delete(
break;
}
+ _RTEMS_Unlock_allocator();
return RTEMS_INVALID_ID;
}
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index ff1fc97099..00a91e8937 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -147,6 +147,8 @@ rtems_status_code rtems_timer_initiate_server(
rtems_id id;
rtems_status_code status;
rtems_task_priority _priority;
+ static boolean initialized = FALSE;
+ boolean tmpInitialized;
/*
* Make sure the requested priority is valid. The if is
@@ -162,15 +164,16 @@ rtems_status_code rtems_timer_initiate_server(
}
/*
- * Just to make sure the test versus create/start operation are atomic.
+ * Just to make sure this is only called once.
*/
_Thread_Disable_dispatch();
+ tmpInitialized = initialized;
+ initialized = TRUE;
+ _Thread_Enable_dispatch();
- if ( _Timer_Server ) {
- _Thread_Enable_dispatch();
+ if ( tmpInitialized )
return RTEMS_INCORRECT_STATE;
- }
/*
* Create the Timer Server with the name the name of "TIME". The attribute
@@ -198,26 +201,14 @@ rtems_status_code rtems_timer_initiate_server(
&id /* get the id back */
);
if (status) {
- _Thread_Enable_dispatch();
+ initialized = FALSE;
return status;
}
- status = rtems_task_start(
- id, /* the id from create */
- (rtems_task_entry) _Timer_Server_body, /* the timer server entry point */
- 0 /* there is no argument */
- );
- if (status) {
- /*
- * One would expect a call to rtems_task_delete() here to clean up
- * but there is actually no way (in normal circumstances) that the
- * start can fail. The id and starting address are known to be
- * be good. If this service fails, something is weirdly wrong on the
- * target such as a stray write in an ISR or incorrect memory layout.
- */
- _Thread_Enable_dispatch();
- return status;
- }
+ /*
+ * Do all the data structure initialization before starting the
+ * Timer Server so we do not have to have a critical section.
+ */
/*
* We work with the TCB pointer, not the ID, so we need to convert
@@ -246,9 +237,27 @@ rtems_status_code rtems_timer_initiate_server(
_Watchdog_Initialize( &_Timer_Server->Timer, _Thread_Delay_ended, id, NULL );
_Watchdog_Initialize( &_Timer_Seconds_timer, _Thread_Delay_ended, id, NULL );
+ /*
+ * Start the timer server
+ */
- _Thread_Enable_dispatch();
- return RTEMS_SUCCESSFUL;
+ status = rtems_task_start(
+ id, /* the id from create */
+ (rtems_task_entry) _Timer_Server_body, /* the timer server entry point */
+ 0 /* there is no argument */
+ );
+ if (status) {
+ /*
+ * One would expect a call to rtems_task_delete() here to clean up
+ * but there is actually no way (in normal circumstances) that the
+ * start can fail. The id and starting address are known to be
+ * be good. If this service fails, something is weirdly wrong on the
+ * target such as a stray write in an ISR or incorrect memory layout.
+ */
+ initialized = FALSE;
+ }
+
+ return status;
}
/*PAGE
diff --git a/cpukit/score/src/threadclose.c b/cpukit/score/src/threadclose.c
index e506b2666d..f8231a1192 100644
--- a/cpukit/score/src/threadclose.c
+++ b/cpukit/score/src/threadclose.c
@@ -2,7 +2,7 @@
* Thread Handler
*
*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -45,10 +45,30 @@ void _Thread_Close(
Thread_Control *the_thread
)
{
+ /*
+ * We assume the Allocator Mutex is locked when we get here.
+ * This provides sufficient protection to let the user extensions
+ * run but as soon as we get back, we will make the thread
+ * disappear and set a transient state on it. So we temporarily
+ * unnest dispatching.
+ */
+ _Thread_Unnest_dispatch();
+
_User_extensions_Thread_delete( the_thread );
+ _Thread_Disable_dispatch();
+
+ /*
+ * Now we are in a dispatching critical section again and we
+ * can take the thread OUT of the published set. It is invalid
+ * to use this thread's Id after this call.
+ */
_Objects_Close( information, &the_thread->Object );
+ /*
+ * By setting the transient state, the thread will not be considered
+ * for scheduling when we remove any blocking states.
+ */
_Thread_Set_state( the_thread, STATES_TRANSIENT );
if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
@@ -56,6 +76,9 @@ void _Thread_Close(
(void) _Watchdog_Remove( &the_thread->Timer );
}
+ /*
+ * The thread might have been FP. So deal with that.
+ */
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
if ( _Thread_Is_allocated_fp( the_thread ) )
@@ -67,11 +90,14 @@ void _Thread_Close(
(void) _Workspace_Free( the_thread->Start.fp_context );
#endif
+ /*
+ * Free the rest of the memory associated with this task
+ * and set the associated pointers to NULL for safety.
+ */
_Thread_Stack_Free( the_thread );
+ the_thread->Start.stack = NULL;
if ( the_thread->extensions )
(void) _Workspace_Free( the_thread->extensions );
-
- the_thread->Start.stack = NULL;
the_thread->extensions = NULL;
}
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index 602fc7840b..3eaff869cf 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -2,7 +2,7 @@
* Thread Handler
*
*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -68,6 +68,13 @@ void _Thread_Create_idle( void )
if ( idle_task_stack_size < STACK_MINIMUM_SIZE )
idle_task_stack_size = STACK_MINIMUM_SIZE;
+ /*
+ * This is only called during initialization and we better be sure
+ * that when _Thread_Initialize unnests dispatch that we do not
+ * do anything stupid.
+ */
+ _Thread_Disable_dispatch();
+
_Thread_Initialize(
&_Thread_Internal_information,
_Thread_Idle,
@@ -82,6 +89,8 @@ void _Thread_Create_idle( void )
(Objects_Name) _Thread_Idle_name
);
+ _Thread_Unnest_dispatch();
+
/*
* WARNING!!! This is necessary to "kick" start the system and
* MUST be done before _Thread_Start is invoked.
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index b2e09727cc..7ef9125a46 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -2,7 +2,7 @@
* Thread Handler
*
*
- * COPYRIGHT (c) 1989-2006.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -61,6 +61,7 @@ boolean _Thread_Initialize(
void *fp_area;
#endif
void *extensions_area;
+ boolean extension_status;
/*
* Initialize the Ada self pointer
@@ -220,10 +221,15 @@ boolean _Thread_Initialize(
_Objects_Open( information, &the_thread->Object, name );
/*
- * Invoke create extensions
+ * We assume the Allocator Mutex is locked and dispatching is
+ * enabled when we get here. We want to be able to run the
+ * user extensions with dispatching enabled. The Allocator
+ * Mutex provides sufficient protection to let the user extensions
+ * run safely.
*/
+ extension_status = _User_extensions_Thread_create( the_thread );
- if ( !_User_extensions_Thread_create( the_thread ) ) {
+ if ( !extension_status ) {
if ( extensions_area )
(void) _Workspace_Free( extensions_area );