source: rtems/cpukit/score/src/threadqprocesstimeout.c @ 91e7b0c

4.115
Last change on this file since 91e7b0c was 91e7b0c, checked in by Sebastian Huber <sebastian.huber@…>, on 03/27/14 at 08:04:47

score: PR2172: _Thread_queue_Extract()

Add _Thread_queue_Extract_with_return_code(). On SMP this sequence in
_Thread_queue_Process_timeout() was broken:

[...]

/*

  • After we enable interrupts here, a lot may happen in the
  • meantime, e.g. nested interrupts may release the resource that
  • times out here. So we enter _Thread_queue_Extract()
  • speculatively. Inside this function we check the actual status
  • under ISR disable protection. This ensures that exactly one
  • executing context performs the extract operation (other parties
  • may call _Thread_queue_Dequeue()). If this context won, then
  • we have a timeout. *
  • We can use the_thread_queue pointer here even if
  • the_thread->Wait.queue is already set to NULL since the extract
  • operation will only use the thread queue discipline to select
  • the right extract operation. The timeout status is set during
  • thread queue initialization. */

we_did_it = _Thread_queue_Extract( the_thread_queue, the_thread );
if ( we_did_it ) {

the_thread->Wait.return_code = the_thread_queue->timeout_status;

}

[...]

In case _Thread_queue_Extract() successfully extracted a thread, then
this thread may start execution on a remote processor immediately and
read the the_thread->Wait.return_code before we update it here with the
timeout status. Thus it observes a successful operation even if it
timed out.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Queue Handler Process Timeout Handler
5 * @ingroup ScoreThreadQ
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/threadqimpl.h>
22#include <rtems/score/threadimpl.h>
23
24void _Thread_queue_Process_timeout(
25  Thread_Control *the_thread
26)
27{
28  Thread_queue_Control *the_thread_queue;
29  ISR_Level             level;
30
31  /*
32   *  If the_thread_queue is not synchronized, then it is either
33   *  "nothing happened", "timeout", or "satisfied".   If the_thread
34   *  is the executing thread, then it is in the process of blocking
35   *  and it is the thread which is responsible for the synchronization
36   *  process.
37   *
38   *  If it is not satisfied, then it is "nothing happened" and
39   *  this is the "timeout" transition.  After a request is satisfied,
40   *  a timeout is not allowed to occur.
41   */
42
43  _ISR_Disable( level );
44  the_thread_queue = the_thread->Wait.queue;
45  if ( the_thread_queue != NULL ) {
46    if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SYNCHRONIZED &&
47         _Thread_Is_executing( the_thread ) ) {
48      if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SATISFIED ) {
49        the_thread->Wait.return_code = the_thread_queue->timeout_status;
50        the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
51      }
52      _ISR_Enable( level );
53    } else {
54      _ISR_Enable( level );
55
56      /*
57       * After we enable interrupts here, a lot may happen in the meantime,
58       * e.g. nested interrupts may release the resource that times out here.
59       * So we enter _Thread_queue_Extract() speculatively.  Inside this
60       * function we check the actual status under ISR disable protection.
61       * This ensures that exactly one executing context performs the extract
62       * operation (other parties may call _Thread_queue_Dequeue()).  If this
63       * context won, then we have a timeout.
64       *
65       * We can use the_thread_queue pointer here even if
66       * the_thread->Wait.queue is already set to NULL since the extract
67       * operation will only use the thread queue discipline to select the
68       * right extract operation.  The timeout status is set during thread
69       * queue initialization.
70       */
71      _Thread_queue_Extract_with_return_code(
72        the_thread_queue,
73        the_thread,
74        the_thread_queue->timeout_status
75      );
76    }
77  } else {
78    _ISR_Enable( level );
79  }
80}
81
Note: See TracBrowser for help on using the repository browser.