summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 );