This is Unofficial EPICS BASE Doxygen Site
osdMutex.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Saskatchewan
3 * EPICS BASE Versions 3.13.7
4 * and higher are distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /*
8  * RTEMS osdMutex.c
9  * Author: W. Eric Norum
10  * eric@cls.usask.ca
11  * (306) 966-6055
12  */
13 
14 /*
15  * We want to access information which is
16  * normally hidden from application programs.
17  */
18 #define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
19 
20 #include <assert.h>
21 #include <stdio.h>
22 #include <rtems.h>
23 #include <rtems/error.h>
24 
25 #include "epicsStdio.h"
26 #include "epicsMutex.h"
27 #include "epicsEvent.h"
28 #include "errlog.h"
29 
30 #define RTEMS_FAST_MUTEX
31 /* #define EPICS_RTEMS_SEMAPHORE_STATS */
32 /*
33  * Some performance tuning instrumentation
34  */
35 #ifdef EPICS_RTEMS_SEMAPHORE_STATS
36 unsigned long semMstat[4];
37 #define SEMSTAT(i) semMstat[i]++;
38 #else
39 #define SEMSTAT(i)
40 #endif
41 
42 struct epicsMutexOSD *
44 {
45  rtems_status_code sc;
46  rtems_id sid;
47  rtems_interrupt_level level;
48  static char c1 = 'a';
49  static char c2 = 'a';
50  static char c3 = 'a';
51 
52  sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1),
53  1,
54  RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
55  0,
56  &sid);
57  if (sc != RTEMS_SUCCESSFUL) {
58  errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc));
59  return NULL;
60  }
61  rtems_interrupt_disable (level);
62  if (c1 == 'z') {
63  if (c2 == 'z') {
64  if (c3 == 'z') {
65  c3 = 'a';
66  }
67  else {
68  c3++;
69  }
70  c2 = 'a';
71  }
72  else {
73  c2++;
74  }
75  c1 = 'a';
76  }
77  else {
78  c1++;
79  }
80  rtems_interrupt_enable (level);
81 #ifdef RTEMS_FAST_MUTEX
82  {
83  Semaphore_Control *the_semaphore;
84  Objects_Locations location;
85 
86  the_semaphore = _Semaphore_Get( sid, &location );
87  _Thread_Enable_dispatch();
88 
89  return (struct epicsMutexOSD *)the_semaphore;
90  }
91 #endif
92  return (struct epicsMutexOSD *)sid;
93 }
94 
96 {
97  rtems_status_code sc;
98  rtems_id sid;
99 #ifdef RTEMS_FAST_MUTEX
100  Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
101  sid = the_semaphore->Object.id;
102 #else
103  sid = (rtems_id)id;
104 #endif
105  sc = rtems_semaphore_delete (sid);
106  if (sc == RTEMS_RESOURCE_IN_USE) {
107  rtems_semaphore_release (sid);
108  sc = rtems_semaphore_delete (sid);
109  }
110  if (sc != RTEMS_SUCCESSFUL)
111  errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n", id, (unsigned long)sid, rtems_status_text (sc));
112 }
113 
115 {
116 #ifdef RTEMS_FAST_MUTEX
117  Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
118  _Thread_Disable_dispatch();
119  _CORE_mutex_Surrender (
120  &the_semaphore->Core_control.mutex,
121  the_semaphore->Object.id,
122  NULL
123  );
124  _Thread_Enable_dispatch();
125 #else
126  epicsEventSignal (id);
127 #endif
128 
129 }
130 
132 {
133 #ifdef RTEMS_FAST_MUTEX
134  Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
135  ISR_Level level;
136  SEMSTAT(0)
137  _ISR_Disable( level );
138  _CORE_mutex_Seize(
139  &the_semaphore->Core_control.mutex,
140  the_semaphore->Object.id,
141  1, /* TRUE or FALSE */
142  0, /* same as passed to obtain -- ticks */
143  level
144  );
145  if (_Thread_Executing->Wait.return_code == 0)
146  return epicsMutexLockOK;
147  else
148  return epicsMutexLockError;
149 #else
150  SEMSTAT(0)
151  return((epicsEventWait (id) == epicsEventWaitOK)
153 #endif
154 }
155 
157 {
158 #ifdef RTEMS_FAST_MUTEX
159  Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
160  ISR_Level level;
161  SEMSTAT(2)
162  _ISR_Disable( level );
163  _CORE_mutex_Seize(
164  &the_semaphore->Core_control.mutex,
165  the_semaphore->Object.id,
166  0, /* TRUE or FALSE */
167  0, /* same as passed to obtain -- ticks */
168  level
169  );
170  if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL)
171  return epicsMutexLockOK;
172  else if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT)
173  return epicsMutexLockTimeout;
174  else
175  return epicsMutexLockError;
176 #else
178  SEMSTAT(2)
179  status = epicsEventTryWait(id);
180  return((status==epicsEventWaitOK
182  : (status==epicsEventWaitTimeout)
185 #endif
186 }
187 
188 LIBCOM_API void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level)
189 {
190 #ifdef RTEMS_FAST_MUTEX
191  Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
192  id = (struct epicsMutexOSD *)the_semaphore->Object.id;
193 #endif
194  epicsEventShow ((epicsEventId)id,level);
195 }
pvd::Status status
#define epicsEventWait(ID)
Definition: osdEvent.h:19
#define NULL
Definition: catime.c:38
void epicsMutexOsdUnlock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:237
#define SEMSTAT(i)
Definition: osdMutex.c:39
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:276
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
Definition: epicsEvent.h:172
epicsMutexOSD * epicsMutexOsdCreate(void)
Definition: osdMutex.c:175
APIs for the epicsMutex mutual exclusion semaphore.
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:301
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
APIs for the epicsEvent binary semaphore.
epicsMutexLockStatus
Definition: epicsMutex.h:51
LIBCOM_API epicsEventStatus epicsEventTryWait(epicsEventId id)
Similar to wait() except that if the event is currenly empty the call will return immediately with st...
Definition: osdEvent.c:145
#define epicsEventWaitOK
Old name provided for backwards compatibility.
Definition: epicsEvent.h:58
void epicsMutexOsdDestroy(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:221
#define epicsEventWaitStatus
Old name provided for backwards compatibility.
Definition: epicsEvent.h:56
LIBCOM_API void epicsEventShow(epicsEventId id, unsigned int level)
Display information about the semaphore.
Definition: osdEvent.c:150
void epicsMutexOsdShow(struct epicsMutexOSD *pmutex, unsigned int level)
Definition: osdMutex.c:329