KallistiOS  ##version##
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
spinlock.h
Go to the documentation of this file.
1 /* KallistiOS ##version##
2 
3  arch/dreamcast/include/spinlock.h
4  Copyright (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) \
71  : "r" (__lock) \
72  : "t", "memory"); \
73  if (!__gotlock) \
74  thd_pass(); \
75  else break; \
76  } \
77  } while (0)
78 
79 /** \brief Free a lock.
80 
81  This macro will unlock the lock that is currently held by the calling
82  thread. Do not use this macro unless you actually hold the lock!
83 
84  \param A A pointer to the spinlock to be unlocked.
85 */
86 #define spinlock_unlock(A) do { \
87  *(A) = 0; \
88  } while (0)
89 
90 /** \brief Determine if a lock is locked.
91 
92  This macro will return whether or not the lock specified is actually locked
93  when it is called. This is NOT a thread-safe way of determining if a lock
94  will be locked when you get around to locking it!
95 
96  \param A A pointer to the spinlock to be checked.
97 */
98 #define spinlock_is_locked(A) ( *(A) != 0 )
99 
100 __END_DECLS
101 
102 #endif /* __ARCH_SPINLOCK_H */
103 
volatile int spinlock_t
Spinlock data type.
Definition: spinlock.h:36
Threading support.