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  * vxWorks (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION
24  *
25  * CAVEAT:
26  * This implementation will not compile on vxWorks SMP architectures.
27  * These architectures provide spinlocks, which must be used instead.
28  *
29  */
30 
31 /* This is needed for vxWorks 6.x to prevent an obnoxious compiler warning */
32 #define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
33 
34 #include <stdlib.h>
35 #include <intLib.h>
36 #include <logLib.h>
37 #include <taskLib.h>
38 
39 #include "cantProceed.h"
40 #include "epicsSpin.h"
41 
42 typedef struct epicsSpin {
43  int key;
44  unsigned int locked;
45 } epicsSpin;
46 
48  return calloc(1, sizeof(epicsSpin));
49 }
50 
52 {
54  if (!ret)
55  cantProceed("epicsSpinMustCreate: epicsSpinCreate failed.");
56  return ret;
57 }
58 
60  free(spin);
61 }
62 
64  int key = intLock();
65 
66  if (!intContext())
67  taskLock();
68  if (spin->locked) {
69  intUnlock(key);
70  if (!intContext()) {
71  taskUnlock();
72  logMsg("epicsSpinLock(%p): Deadlock.\n",
73  (int) spin, 0, 0, 0, 0, 0);
74  cantProceed("Recursive lock, missed unlock or block when locked.");
75  }
76  else {
77  logMsg("epicsSpinLock(%p): Deadlock in ISR.\n"
78  "Recursive lock, missed unlock or block when locked.\n",
79  (int) spin, 0, 0, 0, 0, 0);
80  }
81  return;
82  }
83  spin->key = key;
84  spin->locked = 1;
85 }
86 
88  int key = intLock();
89 
90  if (!intContext())
91  taskLock();
92  if (spin->locked) {
93  intUnlock(key);
94  if (!intContext())
95  taskUnlock();
96  return 1;
97  }
98  spin->key = key;
99  spin->locked = 1;
100  return 0;
101 }
102 
104  int key = spin->key;
105 
106  if (!spin->locked) {
107  logMsg("epicsSpinUnlock(%p): not locked\n",
108  (int) spin, 0, 0, 0, 0, 0);
109  return;
110  }
111  spin->key = spin->locked = 0;
112  intUnlock(key);
113  if (!intContext())
114  taskUnlock();
115 }
int key
Definition: osdSpin.c:43
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
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