This is Unofficial EPICS BASE Doxygen Site
osdSpin.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2012 Helmholtz-Zentrum Berlin
3 * fuer Materialien und Energie GmbH.
4 * Copyright (c) 2012 ITER Organization.
5 * Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
6 * National Laboratory.
7 * Copyright (c) 2013 Brookhaven Science Assoc. as Operator of Brookhaven
8 * National Laboratory.
9 * EPICS BASE is distributed subject to a Software License Agreement found
10 * in file LICENSE that is included with this distribution.
11 \*************************************************************************/
12 
13 /*
14  * Authors: Ralph Lange <Ralph.Lange@gmx.de>
15  * Andrew Johnson <anj@aps.anl.gov>
16  * Michael Davidsaver <mdavidsaver@bnl.gov>
17  *
18  * Inspired by Linux UP spinlocks implemention
19  * include/linux/spinlock_api_up.h
20  */
21 
22 /*
23  * RTEMS (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION
24  *
25  * CAVEAT:
26  * This implementation is intended for UP architectures only.
27  */
28 
29 #define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
30 
31 #include <stdlib.h>
32 #include <rtems.h>
33 
34 #include "cantProceed.h"
35 #include "epicsSpin.h"
36 
37 typedef struct epicsSpin {
38  rtems_interrupt_level level;
39  unsigned int locked;
40 } epicsSpin;
41 
43  return calloc(1, sizeof(epicsSpin));
44 }
45 
47 {
49  if (!ret)
50  cantProceed("epicsSpinMustCreate: epicsSpinCreate failed.");
51  return ret;
52 }
53 
55  free(spin);
56 }
57 
59  rtems_interrupt_level level;
60 
61  rtems_interrupt_disable(level);
62  _Thread_Disable_dispatch();
63  if (spin->locked) {
64  rtems_interrupt_enable(level);
65  _Thread_Enable_dispatch();
66  if (!rtems_interrupt_is_in_progress()) {
67  printk("epicsSpinLock(%p): Deadlock.\n", spin);
68  cantProceed("Recursive lock, missed unlock or block when locked.");
69  }
70  else {
71  printk("epicsSpinLock(%p): Deadlock in ISR.\n"
72  "Recursive lock, missed unlock or block when locked.\n",
73  spin);
74  }
75  return;
76  }
77  spin->level = level;
78  spin->locked = 1;
79 }
80 
82  rtems_interrupt_level level;
83 
84  rtems_interrupt_disable(level);
85  _Thread_Disable_dispatch();
86  if (spin->locked) {
87  rtems_interrupt_enable(level);
88  _Thread_Enable_dispatch();
89  return 1;
90  }
91  spin->level = level;
92  spin->locked = 1;
93  return 0;
94 }
95 
97  rtems_interrupt_level level = spin->level;
98 
99  if (!spin->locked) {
100  printk("epicsSpinUnlock(%p): not locked\n", spin);
101  return;
102  }
103  spin->level = spin->locked = 0;
104  rtems_interrupt_enable (level);
105  _Thread_Enable_dispatch();
106 }
void epicsSpinLock(epicsSpinId spin)
Definition: osdSpin.c:59
int epicsSpinTryLock(epicsSpinId spin)
Definition: osdSpin.c:70
void epicsSpinDestroy(epicsSpinId spin)
Definition: osdSpin.c:54
void epicsSpinUnlock(epicsSpinId spin)
Definition: osdSpin.c:81
rtems_interrupt_level level
Definition: osdSpin.c:38
unsigned int locked
Definition: osdSpin.c:39
LIBCOM_API void cantProceed(const char *msg,...)
Definition: cantProceed.c:54
Routines for code that can&#39;t continue or return after an error.
epicsSpinId epicsSpinMustCreate(void)
Definition: osdSpin.c:46
epicsSpinId epicsSpinCreate(void)
Definition: osdSpin.c:28
struct epicsSpin epicsSpin