source: rtems/cpukit/score/src/threadtimeout.c @ dce48791

5
Last change on this file since dce48791 was dce48791, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/16 at 11:37:59

score: Add Status_Control for all APIs

Unify the status codes of the Classic and POSIX API to use the new enum
Status_Control. This eliminates the Thread_Control::Wait::timeout_code
field and the timeout parameter of _Thread_queue_Enqueue_critical() and
_MPCI_Send_request_packet(). It gets rid of the status code translation
tables and instead uses simple bit operations to get the status for a
particular API. This enables translation of status code constants at
compile time. Add _Thread_Wait_get_status() to avoid direct access of
thread internal data structures.

  • Property mode set to 100644
File size: 2.4 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#include <rtems/score/status.h>
24
25static void _Thread_Do_timeout( Thread_Control *the_thread )
26{
27  the_thread->Wait.return_code = STATUS_TIMEOUT;
28  ( *the_thread->Wait.operations->extract )(
29    the_thread->Wait.queue,
30    the_thread
31  );
32  _Thread_Wait_set_queue( the_thread, NULL );
33  _Thread_Wait_restore_default_operations( the_thread );
34  _Thread_Lock_restore_default( the_thread );
35}
36
37void _Thread_Timeout( Watchdog_Control *watchdog )
38{
39  Thread_Control    *the_thread;
40  void              *thread_lock;
41  ISR_lock_Context   lock_context;
42  Thread_Wait_flags  wait_flags;
43  bool               unblock;
44
45  the_thread = RTEMS_CONTAINER_OF( watchdog, Thread_Control, Timer.Watchdog );
46  thread_lock = _Thread_Lock_acquire( the_thread, &lock_context );
47
48  wait_flags = _Thread_Wait_flags_get( the_thread );
49
50  if ( ( wait_flags & THREAD_WAIT_STATE_READY_AGAIN ) == 0 ) {
51    Thread_Wait_flags wait_class;
52    Thread_Wait_flags ready_again;
53    bool              success;
54
55    _Thread_Do_timeout( the_thread );
56
57    /*
58     * This fence is only necessary for the events, see _Event_Seize().  The
59     * thread queues use the thread lock for synchronization.
60     */
61    _Atomic_Fence( ATOMIC_ORDER_RELEASE );
62
63    wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
64    ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
65    success = _Thread_Wait_flags_try_change_critical(
66      the_thread,
67      wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK,
68      ready_again
69    );
70
71    if ( success ) {
72      unblock = false;
73    } else {
74      _Assert(
75        _Thread_Wait_flags_get( the_thread )
76          == ( wait_class | THREAD_WAIT_STATE_BLOCKED )
77      );
78      _Thread_Wait_flags_set( the_thread, ready_again );
79      unblock = true;
80    }
81  } else {
82    unblock = false;
83  }
84
85  _Thread_Lock_release( thread_lock, &lock_context );
86
87  if ( unblock ) {
88    _Thread_Unblock( the_thread );
89
90#if defined(RTEMS_MULTIPROCESSING)
91    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
92      _Thread_MP_Free_proxy( the_thread );
93    }
94#endif
95  }
96}
Note: See TracBrowser for help on using the repository browser.