source: rtems/cpukit/score/src/threadunpin.c @ 21275b58

5
Last change on this file since 21275b58 was 7097962, checked in by Sebastian Huber <sebastian.huber@…>, on 08/29/18 at 07:43:44

score: Add thread pin/unpin support

Add support to temporarily pin a thread to its current processor. This
may be used to access per-processor data structures in critical sections
with enabled thread dispatching, e.g. a pinned thread is allowed to
block.

Update #3508.

  • Property mode set to 100644
File size: 2.1 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#if HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include <rtems/score/schedulerimpl.h>
14
15void _Thread_Do_unpin( Thread_Control *executing, Per_CPU_Control *cpu_self )
16{
17  ISR_lock_Context         state_lock_context;
18  ISR_lock_Context         scheduler_lock_context;
19  Scheduler_Node          *pinned_node;
20  const Scheduler_Control *pinned_scheduler;
21  Scheduler_Node          *home_node;
22  const Scheduler_Control *home_scheduler;
23  const Scheduler_Control *scheduler;
24
25  _Thread_State_acquire( executing, &state_lock_context );
26
27  executing->Scheduler.pin_level = 0;
28
29  pinned_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE(
30    _Chain_First( &executing->Scheduler.Scheduler_nodes )
31  );
32  pinned_scheduler = _Scheduler_Node_get_scheduler( pinned_node );
33  home_node = _Thread_Scheduler_get_home_node( executing );
34  home_scheduler = _Thread_Scheduler_get_home( executing );
35  scheduler = pinned_scheduler;
36
37  executing->Scheduler.pinned_scheduler = NULL;
38
39  _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
40
41  if ( _Thread_Is_ready( executing ) ) {
42    ( *scheduler->Operations.block )( scheduler, executing, pinned_node );
43  }
44
45  ( *scheduler->Operations.unpin )(
46    scheduler,
47    executing,
48    pinned_node,
49    cpu_self
50  );
51
52  if ( home_node != pinned_node ) {
53    _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
54
55    _Chain_Extract_unprotected( &home_node->Thread.Scheduler_node.Chain );
56    _Chain_Prepend_unprotected(
57      &executing->Scheduler.Scheduler_nodes,
58      &home_node->Thread.Scheduler_node.Chain
59    );
60    scheduler = home_scheduler;
61
62    _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
63  }
64
65  if ( _Thread_Is_ready( executing ) ) {
66    ( *scheduler->Operations.unblock )( scheduler, executing, home_node );
67  }
68
69  _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
70
71  _Thread_State_release( executing, &state_lock_context );
72}
Note: See TracBrowser for help on using the repository browser.