source: rtems/cpukit/score/src/threadtimeout.c @ 10e32a26

5
Last change on this file since 10e32a26 was cc366ec, checked in by Sebastian Huber <sebastian.huber@…>, on 04/24/15 at 10:02:20

score: New thread queue implementation

Use thread wait flags for synchronization. The enqueue operation is now
part of the initial critical section. This is the key change and
enables fine grained locking on SMP for objects using a thread queue
like semaphores and message queues.

Update #2273.

  • Property mode set to 100644
File size: 2.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Wait Timeout
5 *
6 * @ingroup ScoreThread
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2008.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19  #include "config.h"
20#endif
21
22#include <rtems/score/threadimpl.h>
23
24static void _Thread_Do_timeout( Thread_Control *the_thread )
25{
26  the_thread->Wait.return_code = the_thread->Wait.timeout_code;
27  ( *the_thread->Wait.operations->extract )(
28    the_thread->Wait.queue,
29    the_thread
30  );
31  _Thread_Wait_set_queue( the_thread, NULL );
32  _Thread_Wait_restore_default_operations( the_thread );
33  _Thread_Lock_restore_default( the_thread );
34}
35
36void _Thread_Timeout( Objects_Id id, void *arg )
37{
38  Thread_Control    *the_thread;
39  ISR_lock_Control  *thread_lock;
40  ISR_lock_Context   lock_context;
41  Thread_Wait_flags  wait_flags;
42  Thread_Wait_flags  wait_class;
43  Thread_Wait_flags  intend_to_block;
44  Thread_Wait_flags  blocked;
45  bool               success;
46  bool               unblock;
47
48  the_thread = arg;
49  thread_lock = _Thread_Lock_acquire( the_thread, &lock_context );
50
51  wait_flags = _Thread_Wait_flags_get( the_thread );
52  wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
53  intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
54  blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
55  success = _Thread_Wait_flags_try_change_critical(
56    the_thread,
57    intend_to_block,
58    wait_class | THREAD_WAIT_STATE_READY_AGAIN
59  );
60
61  if ( success ) {
62    _Thread_Do_timeout( the_thread );
63    unblock = false;
64  } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
65    _Thread_Wait_flags_set(
66      the_thread,
67      wait_class | THREAD_WAIT_STATE_READY_AGAIN
68    );
69    _Thread_Do_timeout( the_thread );
70    unblock = true;
71  } else {
72    unblock = false;
73  }
74
75  _Thread_Lock_release( thread_lock, &lock_context );
76
77  if ( unblock ) {
78    _Thread_Unblock( the_thread );
79
80#if defined(RTEMS_MULTIPROCESSING)
81    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
82      _Thread_MP_Free_proxy( the_thread );
83    }
84#endif
85  }
86}
Note: See TracBrowser for help on using the repository browser.