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