source: rtems/cpukit/posix/src/mutexunlock.c @ 77fbbd6

5
Last change on this file since 77fbbd6 was de59c065, checked in by Sebastian Huber <sebastian.huber@…>, on 09/27/17 at 13:08:33

posix: Implement self-contained POSIX mutex

POSIX mutexes are now available in all configurations and no longer
depend on --enable-posix.

Update #2514.
Update #3112.

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/**
2 * @file
3 *
4 * @brief Locking and Unlocking a Mutex
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2007.
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/posix/muteximpl.h>
22#include <rtems/posix/posixapi.h>
23
24#include <string.h>
25
26bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex )
27{
28  unsigned long zero;
29  unsigned long flags;
30
31  /* We cannot use memset() and memcmp() due to structure internal padding */
32  zero = 0;
33  zero |= the_mutex->flags;
34#if defined(RTEMS_SMP)
35  zero |= _Atomic_Load_uint(
36    &the_mutex->Recursive.Mutex.Queue.Queue.Lock.next_ticket,
37    ATOMIC_ORDER_RELAXED
38  );
39  zero |= _Atomic_Load_uint(
40    &the_mutex->Recursive.Mutex.Queue.Queue.Lock.now_serving,
41    ATOMIC_ORDER_RELAXED
42  );
43#else
44  zero |= the_mutex->Recursive.Mutex.Queue.reserved[ 0 ];
45  zero |= the_mutex->Recursive.Mutex.Queue.reserved[ 1 ];
46#endif
47  zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.heads;
48  zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.owner;
49  zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.name;
50  zero |= the_mutex->Recursive.nest_level;
51  zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_left;
52  zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_right;
53  zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_parent;
54  zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_color;
55  zero |= (unsigned long) the_mutex->Priority_ceiling.priority;
56  zero |= (unsigned long) (the_mutex->Priority_ceiling.priority >> 32);
57  zero |= (unsigned long) the_mutex->scheduler;
58
59  if ( zero != 0 ) {
60    return false;
61  }
62
63  flags = (uintptr_t) the_mutex ^ POSIX_MUTEX_MAGIC;
64  flags &= ~POSIX_MUTEX_FLAGS_MASK;
65  the_mutex->flags = flags;
66  return true;
67}
68
69/*
70 *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
71 *
72 *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
73 */
74
75int pthread_mutex_unlock(
76  pthread_mutex_t           *mutex
77)
78{
79  POSIX_Mutex_Control  *the_mutex;
80  unsigned long         flags;
81  Thread_queue_Context  queue_context;
82  Thread_Control       *executing;
83  Status_Control        status;
84
85  the_mutex = _POSIX_Mutex_Get( mutex );
86  POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags );
87
88  executing = _POSIX_Mutex_Acquire( the_mutex, &queue_context );
89
90  switch ( _POSIX_Mutex_Get_protocol( flags ) ) {
91    case POSIX_MUTEX_PRIORITY_CEILING:
92      status = _POSIX_Mutex_Ceiling_surrender(
93        the_mutex,
94        executing,
95        &queue_context
96      );
97      break;
98    case POSIX_MUTEX_NO_PROTOCOL:
99      status = _POSIX_Mutex_Surrender(
100        the_mutex,
101        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
102        executing,
103        &queue_context
104      );
105      break;
106    default:
107      _Assert(
108        _POSIX_Mutex_Get_protocol( flags ) == POSIX_MUTEX_PRIORITY_INHERIT
109      );
110      status = _POSIX_Mutex_Surrender(
111        the_mutex,
112        POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS,
113        executing,
114        &queue_context
115      );
116      break;
117  }
118
119  return _POSIX_Get_error( status );
120}
Note: See TracBrowser for help on using the repository browser.