source: rtems/cpukit/score/src/once.c @ fce900b5

5
Last change on this file since fce900b5 was 6c2b8a4b, checked in by Sebastian Huber <sebastian.huber@…>, on 11/29/17 at 05:23:27

score: Use self-contained API mutex

Use a self-contained recursive mutex for API_Mutex_Control. The API
mutexes are protected against asynchronous thread cancellation.

Add dedicated mutexes for libatomic and TOD.

Close #2629.
Close #2630.

  • Property mode set to 100644
File size: 1.5 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-1999.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11  #include "config.h"
12#endif
13
14#include <rtems/score/onceimpl.h>
15#include <rtems/score/apimutex.h>
16
17#include <errno.h>
18
19#define ONCE_STATE_NOT_RUN  0
20#define ONCE_STATE_RUNNING  1
21#define ONCE_STATE_COMPLETE 2
22
23int _Once( unsigned char *once_state, void ( *init_routine )( void ) )
24{
25  int eno = 0;
26
27  if ( *once_state != ONCE_STATE_COMPLETE ) {
28    _Once_Lock();
29
30    /*
31     * Getting to here means the once_control is locked so we have:
32     *  1. The init has not run and the state is ONCE_STATE_NOT_RUN.
33     *  2. The init has finished and the state is ONCE_STATE_COMPLETE (already
34     *     caught by the previous if).
35     *  3. The init is being run by this thread and the state
36     *     ONCE_STATE_RUNNING so we are nesting. This is an error.
37     */
38
39    switch ( *once_state ) {
40      case ONCE_STATE_NOT_RUN:
41        *once_state = ONCE_STATE_RUNNING;
42        ( *init_routine )();
43        *once_state = ONCE_STATE_COMPLETE;
44        break;
45      case ONCE_STATE_RUNNING:
46        eno = EINVAL;
47        break;
48      default:
49        break;
50    }
51
52    _Once_Unlock();
53  }
54
55  return eno;
56}
57
58static API_Mutex_Control _Once_Mutex = API_MUTEX_INITIALIZER( "_Once" );
59
60void _Once_Lock( void )
61{
62  _API_Mutex_Lock( &_Once_Mutex );
63}
64
65void _Once_Unlock( void )
66{
67  _API_Mutex_Unlock( &_Once_Mutex );
68}
Note: See TracBrowser for help on using the repository browser.