summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-04 11:28:12 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-06 08:17:05 +0200
commitf65f803a269784f6f05658054dd1709497ca5049 (patch)
treef82ea374a9dc184e2a9f6e58f6f36a9094f14852
parentposix: Avoid Giant lock in pthread_equal() (diff)
downloadrtems-f65f803a269784f6f05658054dd1709497ca5049.tar.bz2
score: Avoid Giant lock for CBS scheduler
Update #2555.
-rw-r--r--cpukit/score/src/schedulercbsattachthread.c54
-rw-r--r--cpukit/score/src/schedulercbsdetachthread.c46
-rw-r--r--cpukit/score/src/schedulercbsgetexecutiontime.c37
-rw-r--r--cpukit/score/src/schedulercbsgetremainingbudget.c33
4 files changed, 93 insertions, 77 deletions
diff --git a/cpukit/score/src/schedulercbsattachthread.c b/cpukit/score/src/schedulercbsattachthread.c
index 2d1e0ee243..49162f6620 100644
--- a/cpukit/score/src/schedulercbsattachthread.c
+++ b/cpukit/score/src/schedulercbsattachthread.c
@@ -26,42 +26,46 @@ int _Scheduler_CBS_Attach_thread (
rtems_id task_id
)
{
- Objects_Locations location;
- Thread_Control *the_thread;
+ Scheduler_CBS_Server *server;
+ ISR_lock_Context lock_context;
+ Thread_Control *the_thread;
+ Scheduler_CBS_Node *node;
- if ( server_id >= _Scheduler_CBS_Maximum_servers )
+ if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
+ }
+
+ server = &_Scheduler_CBS_Server_list[ server_id ];
- /* Server is not valid. */
- if ( !_Scheduler_CBS_Server_list[server_id].initialized )
+ if ( !server->initialized ) {
return SCHEDULER_CBS_ERROR_NOSERVER;
+ }
- /* Server is already attached to a thread. */
- if ( _Scheduler_CBS_Server_list[server_id].task_id != -1 )
+ if ( server->task_id != -1 ) {
return SCHEDULER_CBS_ERROR_FULL;
+ }
- the_thread = _Thread_Get(task_id, &location);
- /* The routine _Thread_Get may disable dispatch and not enable again. */
- if ( the_thread ) {
- Scheduler_CBS_Node *node = _Scheduler_CBS_Thread_get_node( the_thread );
-
- /* Thread is already attached to a server. */
- if ( node->cbs_server ) {
- _Objects_Put( &the_thread->Object );
- return SCHEDULER_CBS_ERROR_FULL;
- }
+ the_thread = _Thread_Get_interrupt_disable( task_id, &lock_context );
- _Scheduler_CBS_Server_list[server_id].task_id = task_id;
- node->cbs_server = &_Scheduler_CBS_Server_list[server_id];
+ if ( the_thread == NULL ) {
+ return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
+ }
- the_thread->budget_callout = _Scheduler_CBS_Budget_callout;
- the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
- the_thread->is_preemptible = true;
+ node = _Scheduler_CBS_Thread_get_node( the_thread );
- _Objects_Put( &the_thread->Object );
- } else {
- return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
+ if ( node->cbs_server != NULL ) {
+ _ISR_lock_ISR_enable( &lock_context );
+ return SCHEDULER_CBS_ERROR_FULL;
}
+ node->cbs_server = server;
+
+ server->task_id = task_id;
+
+ the_thread->budget_callout = _Scheduler_CBS_Budget_callout;
+ the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
+ the_thread->is_preemptible = true;
+
+ _ISR_lock_ISR_enable( &lock_context );
return SCHEDULER_CBS_OK;
}
diff --git a/cpukit/score/src/schedulercbsdetachthread.c b/cpukit/score/src/schedulercbsdetachthread.c
index 97ce1ad024..872d4b8df8 100644
--- a/cpukit/score/src/schedulercbsdetachthread.c
+++ b/cpukit/score/src/schedulercbsdetachthread.c
@@ -27,34 +27,40 @@ int _Scheduler_CBS_Detach_thread (
rtems_id task_id
)
{
- Objects_Locations location;
- Thread_Control *the_thread;
+ Scheduler_CBS_Server *server;
+ ISR_lock_Context lock_context;
+ Thread_Control *the_thread;
+ Scheduler_CBS_Node *node;
- if ( server_id >= _Scheduler_CBS_Maximum_servers )
- return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
- /* Server is not valid. */
- if ( !_Scheduler_CBS_Server_list[server_id].initialized )
- return SCHEDULER_CBS_ERROR_NOSERVER;
- /* Thread and server are not attached. */
- if ( _Scheduler_CBS_Server_list[server_id].task_id != task_id )
+ if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
+ }
- the_thread = _Thread_Get(task_id, &location);
- /* The routine _Thread_Get may disable dispatch and not enable again. */
- if ( the_thread ) {
- Scheduler_CBS_Node *node = _Scheduler_CBS_Thread_get_node( the_thread );
+ server = &_Scheduler_CBS_Server_list[ server_id ];
- _Scheduler_CBS_Server_list[server_id].task_id = -1;
- node->cbs_server = NULL;
+ if ( !server->initialized ) {
+ return SCHEDULER_CBS_ERROR_NOSERVER;
+ }
- the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
- the_thread->budget_callout = the_thread->Start.budget_callout;
- the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ if ( server->task_id != task_id ) {
+ return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
+ }
+
+ the_thread = _Thread_Get_interrupt_disable( task_id, &lock_context );
- _Objects_Put( &the_thread->Object );
- } else {
+ if ( the_thread == NULL ) {
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
}
+ node = _Scheduler_CBS_Thread_get_node( the_thread );
+ node->cbs_server = NULL;
+
+ server->task_id = -1;
+
+ the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
+ the_thread->budget_callout = the_thread->Start.budget_callout;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+
+ _ISR_lock_ISR_enable( &lock_context );
return SCHEDULER_CBS_OK;
}
diff --git a/cpukit/score/src/schedulercbsgetexecutiontime.c b/cpukit/score/src/schedulercbsgetexecutiontime.c
index ee139e640d..a16d297b48 100644
--- a/cpukit/score/src/schedulercbsgetexecutiontime.c
+++ b/cpukit/score/src/schedulercbsgetexecutiontime.c
@@ -28,30 +28,33 @@ int _Scheduler_CBS_Get_execution_time (
time_t *abs_time
)
{
- Objects_Locations location;
- Thread_Control *the_thread;
+ Scheduler_CBS_Server *server;
+ ISR_lock_Context lock_context;
+ Thread_Control *the_thread;
- if ( server_id >= _Scheduler_CBS_Maximum_servers )
+ if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
- if ( !_Scheduler_CBS_Server_list[server_id].initialized )
+ }
+
+ server = &_Scheduler_CBS_Server_list[ server_id ];
+
+ if ( !server->initialized ) {
return SCHEDULER_CBS_ERROR_NOSERVER;
- if ( _Scheduler_CBS_Server_list[server_id].task_id == -1 ) {
+ }
+
+ if ( server->task_id == -1 ) {
*exec_time = 0;
return SCHEDULER_CBS_OK;
}
- the_thread = _Thread_Get(
- _Scheduler_CBS_Server_list[server_id].task_id,
- &location
- );
- /* The routine _Thread_Get may disable dispatch and not enable again. */
- if ( the_thread ) {
- *exec_time = _Scheduler_CBS_Server_list[server_id].parameters.budget -
- the_thread->cpu_time_budget;
- _Objects_Put( &the_thread->Object );
- }
- else {
- *exec_time = _Scheduler_CBS_Server_list[server_id].parameters.budget;
+ the_thread = _Thread_Get_interrupt_disable( server->task_id, &lock_context );
+
+ if ( the_thread != NULL ) {
+ *exec_time = server->parameters.budget - the_thread->cpu_time_budget;
+ _ISR_lock_ISR_enable( &lock_context );
+ } else {
+ *exec_time = server->parameters.budget;
}
+
return SCHEDULER_CBS_OK;
}
diff --git a/cpukit/score/src/schedulercbsgetremainingbudget.c b/cpukit/score/src/schedulercbsgetremainingbudget.c
index a031ba4e87..947a811bce 100644
--- a/cpukit/score/src/schedulercbsgetremainingbudget.c
+++ b/cpukit/score/src/schedulercbsgetremainingbudget.c
@@ -26,28 +26,31 @@ int _Scheduler_CBS_Get_remaining_budget (
time_t *remaining_budget
)
{
- Objects_Locations location;
- Thread_Control *the_thread;
+ Scheduler_CBS_Server *server;
+ ISR_lock_Context lock_context;
+ Thread_Control *the_thread;
- if ( server_id >= _Scheduler_CBS_Maximum_servers )
+ if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
- if ( !_Scheduler_CBS_Server_list[server_id].initialized )
+ }
+
+ server = &_Scheduler_CBS_Server_list[ server_id ];
+
+ if ( !server->initialized ) {
return SCHEDULER_CBS_ERROR_NOSERVER;
- if ( _Scheduler_CBS_Server_list[server_id].task_id == -1 ) {
- *remaining_budget = _Scheduler_CBS_Server_list[server_id].parameters.budget;
+ }
+
+ if ( server->task_id == -1 ) {
+ *remaining_budget = server->parameters.budget;
return SCHEDULER_CBS_OK;
}
- the_thread = _Thread_Get(
- _Scheduler_CBS_Server_list[server_id].task_id,
- &location
- );
- /* The routine _Thread_Get may disable dispatch and not enable again. */
- if ( the_thread ) {
+ the_thread = _Thread_Get_interrupt_disable( server->task_id, &lock_context );
+
+ if ( the_thread != NULL ) {
*remaining_budget = the_thread->cpu_time_budget;
- _Objects_Put( &the_thread->Object );
- }
- else {
+ _ISR_lock_ISR_enable( &lock_context );
+ } else {
*remaining_budget = 0;
}