KallistiOS  2.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
spinlock.h
Go to the documentation of this file.
1 /* KallistiOS 2.0.0
2 
3  arch/dreamcast/include/spinlock.h
4  (c)2001 Dan Potter
5 
6 */
7 
8 /** \file arch/spinlock.h
9  \brief Simple locking.
10 
11  This file contains definitions for very simple locks. Most of the time, you
12  will probably not use such low-level locking, but will opt for something
13  more fully featured like mutexes, semaphores, reader-writer semaphores, or
14  recursive locks.
15 
16  \author Dan Potter
17 
18  \see kos/sem.h
19  \see kos/mutex.h
20  \see kos/rwsem.h
21  \see kos/recursive_lock.h
22 */
23 
24 #ifndef __ARCH_SPINLOCK_H
25 #define __ARCH_SPINLOCK_H
26 
27 /* Defines processor specific spinlocks */
28 
29 #include <sys/cdefs.h>
30 __BEGIN_DECLS
31 
32 /* DC implementation uses threads most of the time */
33 #include <kos/thread.h>
34 
35 /** \brief Spinlock data type. */
36 typedef volatile int spinlock_t;
37 
38 /** \brief Spinlock initializer.
39 
40  All created spinlocks should be initialized with this initializer so that
41  they are in a sane state, ready to be used.
42 */
43 #define SPINLOCK_INITIALIZER 0
44 
45 /** \brief Initialize a spinlock.
46 
47  This function-like macro abstracts initializing a spinlock, in case the
48  initializer is not applicable to what you are doing.
49 
50  \param A A pointer to the spinlock to be initialized.
51 */
52 #define spinlock_init(A) *(A) = SPINLOCK_INITIALIZER
53 
54 /* Note here that even if threads aren't enabled, we'll still set the
55  lock so that it can be used for anti-IRQ protection (e.g., malloc) */
56 
57 /** \brief Spin on a lock.
58 
59  This macro will spin on the lock, and will not return until the lock has
60  been obtained for the calling thread.
61 
62  \param A A pointer to the spinlock to be locked.
63 */
64 #define spinlock_lock(A) do { \
65  spinlock_t * __lock = A; \
66  int __gotlock = 0; \
67  while(1) { \
68  asm volatile ("tas.b @%1\n\t" \
69  "movt %0\n\t" \
70  : "=r" (__gotlock) : "r" (__lock) : "t", "memory"); \
71  if (!__gotlock) \
72  thd_pass(); \
73  else break; \
74  } \
75  } while (0)
76 
77 /** \brief Free a lock.
78 
79  This macro will unlock the lock that is currently held by the calling
80  thread. Do not use this macro unless you actually hold the lock!
81 
82  \param A A pointer to the spinlock to be unlocked.
83 */
84 #define spinlock_unlock(A) do { \
85  *(A) = 0; \
86  } while (0)
87 
88 /** \brief Determine if a lock is locked.
89 
90  This macro will return whether or not the lock specified is actually locked
91  when it is called. This is NOT a thread-safe way of determining if a lock
92  will be locked when you get around to locking it!
93 
94  \param A A pointer to the spinlock to be checked.
95 */
96 #define spinlock_is_locked(A) ( *(A) != 0 )
97 
98 __END_DECLS
99 
100 #endif /* __ARCH_SPINLOCK_H */
101