diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-03-29 12:06:55 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-03-29 12:06:55 +0200 |
commit | 16832b0d9e1f6448a57b6f5f2909cff7ad360706 (patch) | |
tree | 772708cb85a765b1a3c5b0437a14027c581b7e28 /cpukit/score/src | |
parent | score: Allow MPCI packet receive function to block (diff) | |
download | rtems-16832b0d9e1f6448a57b6f5f2909cff7ad360706.tar.bz2 |
score: Fix multiprocessing thread proxies
We must provide thread queue heads for the thread wait information for
each thread proxy (thread queue heads were introduced by
d7665823b208daefb6855591d808e1f3075cedcb). The thread proxy must be
allocated before the enqueue operation.
Diffstat (limited to 'cpukit/score/src')
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 4 | ||||
-rw-r--r-- | cpukit/score/src/threadmp.c | 39 | ||||
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 11 |
3 files changed, 40 insertions, 14 deletions
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index bcf03bf833..18d29f8d1a 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -160,9 +160,7 @@ bool _Thread_Initialize( the_thread->Start.budget_algorithm = budget_algorithm; the_thread->Start.budget_callout = budget_callout; - _ISR_lock_Initialize( &the_thread->Timer.Lock, "Thread Timer" ); - the_thread->Timer.header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ]; - _Watchdog_Preinitialize( &the_thread->Timer.Watchdog, cpu ); + _Thread_Timer_initialize( &the_thread->Timer, cpu ); switch ( budget_algorithm ) { case THREAD_CPU_BUDGET_ALGORITHM_NONE: diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c index a0846246a5..2d7e92496d 100644 --- a/cpukit/score/src/threadmp.c +++ b/cpukit/score/src/threadmp.c @@ -22,6 +22,8 @@ #include <rtems/score/isrlevel.h> #include <rtems/score/wkspace.h> +#include <string.h> + Chain_Control _Thread_MP_Active_proxies; Chain_Control _Thread_MP_Inactive_proxies; @@ -30,6 +32,10 @@ void _Thread_MP_Handler_initialization ( uint32_t maximum_proxies ) { + size_t proxy_size; + size_t alloc_size; + char *proxies; + uint32_t i; _Chain_Initialize_empty( &_Thread_MP_Active_proxies ); @@ -38,16 +44,29 @@ void _Thread_MP_Handler_initialization ( return; } + proxy_size = sizeof( Thread_Proxy_control ) + + THREAD_QUEUE_HEADS_SIZE( _Scheduler_Count ); + alloc_size = maximum_proxies * proxy_size; + proxies = _Workspace_Allocate_or_fatal_error( alloc_size ); + memset( proxies, 0, alloc_size ); _Chain_Initialize( &_Thread_MP_Inactive_proxies, - _Workspace_Allocate_or_fatal_error( - maximum_proxies * sizeof( Thread_Proxy_control ) - ), + proxies, maximum_proxies, - sizeof( Thread_Proxy_control ) + proxy_size ); + for ( i = 0 ; i < maximum_proxies ; ++i ) { + Thread_Proxy_control *proxy; + + proxy = (Thread_Proxy_control *) ( proxies + i * proxy_size ); + + _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) ); + + proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ]; + _Thread_queue_Heads_initialize( proxy->Wait.spare_heads ); + } } Thread_Control *_Thread_MP_Allocate_proxy ( @@ -60,10 +79,12 @@ Thread_Control *_Thread_MP_Allocate_proxy ( the_thread = (Thread_Control *)_Chain_Get( &_Thread_MP_Inactive_proxies ); if ( !_Thread_Is_null( the_thread ) ) { + Thread_Control *executing; + executing = _Thread_Executing; the_proxy = (Thread_Proxy_control *) the_thread; - _Thread_Executing->Wait.return_code = THREAD_STATUS_PROXY_BLOCKING; + executing->Wait.return_code = THREAD_STATUS_PROXY_BLOCKING; the_proxy->receive_packet = _MPCI_Receive_server_tcb->receive_packet; @@ -74,7 +95,13 @@ Thread_Control *_Thread_MP_Allocate_proxy ( the_proxy->current_state = _States_Set( STATES_DORMANT, the_state ); - the_proxy->Wait = _Thread_Executing->Wait; + the_proxy->Wait.id = executing->Wait.id; + the_proxy->Wait.count = executing->Wait.count; + the_proxy->Wait.return_argument = executing->Wait.return_argument; + the_proxy->Wait.return_argument_second = executing->Wait.return_argument_second; + the_proxy->Wait.option = executing->Wait.option; + the_proxy->Wait.return_code = executing->Wait.return_code; + the_proxy->Wait.timeout_code = executing->Wait.timeout_code; _Chain_Append( &_Thread_MP_Active_proxies, &the_proxy->Active ); diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index e7751359d7..803b5568b3 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -58,6 +58,12 @@ void _Thread_queue_Enqueue_critical( Per_CPU_Control *cpu_self; bool success; +#if defined(RTEMS_MULTIPROCESSING) + if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) { + the_thread = _Thread_MP_Allocate_proxy( state ); + } +#endif + _Thread_Lock_set( the_thread, &queue->Lock ); _Thread_Wait_set_queue( the_thread, queue ); @@ -69,11 +75,6 @@ void _Thread_queue_Enqueue_critical( cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Thread_queue_Queue_release( queue, lock_context ); -#if defined(RTEMS_MULTIPROCESSING) - if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) - the_thread = _Thread_MP_Allocate_proxy( state ); - else -#endif /* * Set the blocking state for this thread queue in the thread. */ |