source: rtems/cpukit/rtems/src/eventtimeout.c @ 7d6e94b

4.115
Last change on this file since 7d6e94b was 7d6e94b, checked in by Sebastian Huber <sebastian.huber@…>, on 03/04/15 at 07:02:19

score: Implement fine-grained locking for events

Use the ISR lock of the thread object to protect the event state and
use the Giant lock only for the blocking operations.

Update #2273.

  • Property mode set to 100644
File size: 2.3 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Timeout Event
5 *  @ingroup ClassicEvent
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/rtems/eventimpl.h>
22#include <rtems/score/threadimpl.h>
23
24void _Event_Timeout(
25  Objects_Id  id,
26  void       *arg
27)
28{
29  Thread_Control    *the_thread;
30  Objects_Locations  location;
31  ISR_lock_Context   lock_context;
32  Thread_Wait_flags  wait_flags;
33  Thread_Wait_flags  wait_class;
34  Thread_Wait_flags  intend_to_block;
35  Thread_Wait_flags  blocked;
36  bool               success;
37  bool               unblock;
38
39  the_thread = _Thread_Acquire( id, &location, &lock_context );
40  switch ( location ) {
41    case OBJECTS_LOCAL:
42      wait_flags = _Thread_Wait_flags_get( the_thread );
43      wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
44      intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
45      blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
46      success = _Thread_Wait_flags_try_change_critical(
47        the_thread,
48        intend_to_block,
49        wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT
50      );
51
52      if ( success ) {
53        the_thread->Wait.return_code = RTEMS_TIMEOUT;
54        unblock = false;
55      } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
56        the_thread->Wait.return_code = RTEMS_TIMEOUT;
57        _Thread_Wait_flags_set(
58          the_thread,
59          wait_class | THREAD_WAIT_STATE_TIMEOUT
60        );
61        unblock = true;
62      } else {
63        unblock = false;
64      }
65
66      if ( unblock ) {
67        Per_CPU_Control *cpu_self;
68
69        cpu_self = _Objects_Release_and_thread_dispatch_disable(
70          &the_thread->Object,
71          &lock_context
72        );
73        _Giant_Acquire( cpu_self );
74
75        _Thread_Unblock( the_thread );
76
77        _Giant_Release( cpu_self );
78        _Thread_Dispatch_enable( cpu_self );
79      } else {
80        _Objects_Release_and_ISR_enable( &the_thread->Object, &lock_context );
81      }
82
83      break;
84#if defined(RTEMS_MULTIPROCESSING)
85    case OBJECTS_REMOTE:  /* impossible */
86#endif
87    case OBJECTS_ERROR:
88      break;
89  }
90}
Note: See TracBrowser for help on using the repository browser.