1 /*
2  * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef _SYS_LOCK_H_
27 #define _SYS_LOCK_H_
28 
29 #include <sys/cdefs.h>
30 #include <stddef.h>
31 
32 __BEGIN_DECLS
33 
34 struct timespec;
35 
36 struct _Thread_Control;
37 
38 struct _Thread_queue_Heads;
39 
40 struct _Ticket_lock_Control {
41 	unsigned int _next_ticket;
42 	unsigned int _now_serving;
43 };
44 
45 struct _Thread_queue_Queue {
46 	struct _Thread_queue_Heads *_heads;
47 	struct _Ticket_lock_Control _Lock;
48 };
49 
50 struct _Mutex_Control {
51 	struct _Thread_queue_Queue _Queue;
52 	struct _Thread_Control *_owner;
53 };
54 
55 struct _Mutex_recursive_Control {
56 	struct _Mutex_Control _Mutex;
57 	unsigned int _nest_level;
58 };
59 
60 struct _Condition_Control {
61 	struct _Thread_queue_Queue _Queue;
62 };
63 
64 struct _Semaphore_Control {
65 	struct _Thread_queue_Queue _Queue;
66 	unsigned int _count;
67 };
68 
69 struct _Futex_Control {
70 	struct _Thread_queue_Queue _Queue;
71 };
72 
73 #define _THREAD_QUEUE_INITIALIZER { 0, { 0, 0 } }
74 
75 #define _MUTEX_INITIALIZER { _THREAD_QUEUE_INITIALIZER, 0 }
76 
77 #define _MUTEX_RECURSIVE_INITIALIZER { _MUTEX_INITIALIZER, 0 }
78 
79 #define _CONDITION_INITIALIZER { _THREAD_QUEUE_INITIALIZER }
80 
81 #define _SEMAPHORE_INITIALIZER(_count) { _THREAD_QUEUE_INITIALIZER, _count }
82 
83 #define _FUTEX_INITIALIZER { _THREAD_QUEUE_INITIALIZER }
84 
85 static inline void
_Mutex_Initialize(struct _Mutex_Control * _mutex)86 _Mutex_Initialize(struct _Mutex_Control *_mutex)
87 {
88 	struct _Mutex_Control _init = _MUTEX_INITIALIZER;
89 
90 	*_mutex = _init;
91 }
92 
93 void _Mutex_Acquire(struct _Mutex_Control *);
94 
95 int _Mutex_Acquire_timed(struct _Mutex_Control *, const struct timespec *);
96 
97 int _Mutex_Try_acquire(struct _Mutex_Control *);
98 
99 void _Mutex_Release(struct _Mutex_Control *);
100 
101 static inline void
_Mutex_Destroy(struct _Mutex_Control * _mutex)102 _Mutex_Destroy(struct _Mutex_Control *_mutex)
103 {
104 
105 	(void)_mutex;
106 }
107 
108 static inline void
_Mutex_recursive_Initialize(struct _Mutex_recursive_Control * _mutex)109 _Mutex_recursive_Initialize(struct _Mutex_recursive_Control *_mutex)
110 {
111 	struct _Mutex_recursive_Control _init = _MUTEX_RECURSIVE_INITIALIZER;
112 
113 	*_mutex = _init;
114 }
115 
116 void _Mutex_recursive_Acquire(struct _Mutex_recursive_Control *);
117 
118 int _Mutex_recursive_Acquire_timed(struct _Mutex_recursive_Control *,
119     const struct timespec *);
120 
121 int _Mutex_recursive_Try_acquire(struct _Mutex_recursive_Control *);
122 
123 void _Mutex_recursive_Release(struct _Mutex_recursive_Control *);
124 
125 static inline void
_Mutex_recursive_Destroy(struct _Mutex_recursive_Control * _mutex)126 _Mutex_recursive_Destroy(struct _Mutex_recursive_Control *_mutex)
127 {
128 
129 	(void)_mutex;
130 }
131 
132 static inline void
_Condition_Initialize(struct _Condition_Control * _cond)133 _Condition_Initialize(struct _Condition_Control *_cond)
134 {
135 	struct _Condition_Control _init = _CONDITION_INITIALIZER;
136 
137 	*_cond = _init;
138 }
139 
140 void _Condition_Wait(struct _Condition_Control *, struct _Mutex_Control *);
141 
142 int _Condition_Wait_timed(struct _Condition_Control *,
143     struct _Mutex_Control *, const struct timespec *);
144 
145 void _Condition_Wait_recursive(struct _Condition_Control *,
146     struct _Mutex_recursive_Control *);
147 
148 int _Condition_Wait_recursive_timed(struct _Condition_Control *,
149     struct _Mutex_recursive_Control *, const struct timespec *);
150 
151 void _Condition_Signal(struct _Condition_Control *);
152 
153 void _Condition_Broadcast(struct _Condition_Control *);
154 
155 static inline void
_Condition_Destroy(struct _Condition_Control * _cond)156 _Condition_Destroy(struct _Condition_Control *_cond)
157 {
158 
159 	(void)_cond;
160 }
161 
162 static inline void
_Semaphore_Initialize(struct _Semaphore_Control * _semaphore,unsigned int _count)163 _Semaphore_Initialize(struct _Semaphore_Control *_semaphore,
164     unsigned int _count)
165 {
166 	struct _Semaphore_Control _init = _SEMAPHORE_INITIALIZER(_count);
167 
168 	*_semaphore = _init;
169 }
170 
171 void _Semaphore_Wait(struct _Semaphore_Control *);
172 
173 void _Semaphore_Post(struct _Semaphore_Control *);
174 
175 static inline void
_Semaphore_Destroy(struct _Semaphore_Control * _semaphore)176 _Semaphore_Destroy(struct _Semaphore_Control *_semaphore)
177 {
178 
179 	(void)_semaphore;
180 }
181 
182 static inline void
_Futex_Initialize(struct _Futex_Control * _futex)183 _Futex_Initialize(struct _Futex_Control *_futex)
184 {
185 	struct _Futex_Control _init = _FUTEX_INITIALIZER;
186 
187 	*_futex = _init;
188 }
189 
190 int _Futex_Wait(struct _Futex_Control *, int *, int);
191 
192 int _Futex_Wake(struct _Futex_Control *, int);
193 
194 static inline void
_Futex_Destroy(struct _Futex_Control * _futex)195 _Futex_Destroy(struct _Futex_Control *_futex)
196 {
197 
198 	(void)_futex;
199 }
200 
201 int _Sched_Count(void);
202 
203 int _Sched_Index(void);
204 
205 int _Sched_Name_to_index(const char *, size_t);
206 
207 int _Sched_Processor_count(int);
208 
209 /* Newlib internal locks */
210 
211 typedef struct _Mutex_Control _LOCK_T;
212 
213 typedef struct _Mutex_recursive_Control _LOCK_RECURSIVE_T;
214 
215 #define __LOCK_INIT(_qualifier, _designator) \
216     _qualifier _LOCK_T _designator = _MUTEX_INITIALIZER
217 
218 #define __LOCK_INIT_RECURSIVE(_qualifier, _designator) \
219     _qualifier _LOCK_RECURSIVE_T _designator = _MUTEX_RECURSIVE_INITIALIZER
220 
221 #define __lock_init(_lock) _Mutex_Initialize(&_lock)
222 #define __lock_acquire(_lock) _Mutex_Acquire(&_lock)
223 #define __lock_try_acquire(lock) _Mutex_Try_acquire(&_lock)
224 #define __lock_release(_lock) _Mutex_Release(&_lock)
225 #define __lock_close(_lock) _Mutex_Destroy(&_lock)
226 
227 #define __lock_init_recursive(_lock) _Mutex_recursive_Initialize(&_lock)
228 #define __lock_acquire_recursive(_lock) _Mutex_recursive_Acquire(&_lock)
229 #define __lock_try_acquire_recursive(lock) _Mutex_recursive_Try_acquire(&_lock)
230 #define __lock_release_recursive(_lock) _Mutex_recursive_Release(&_lock)
231 #define __lock_close_recursive(_lock) _Mutex_recursive_Destroy(&_lock)
232 
233 __END_DECLS
234 
235 #endif /* _SYS_LOCK_H_ */
236