]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/dde/include/ddekit/__usem_wrap.h
update
[l4.git] / l4 / pkg / dde / include / ddekit / __usem_wrap.h
1 /*
2  * This file is part of DDEKit.
3  *
4  * (c) 2009-2010 Bjoern Doebel <doebel@os.inf.tu-dresden.de>
5  *               Christian Helmuth <ch12@os.inf.tu-dresden.de>
6  *               Thomas Friebel <tf13@os.inf.tu-dresden.de>
7  *     economic rights: Technische Universitaet Dresden (Germany)
8  *
9  * This file is part of TUD:OS and distributed under the terms of the
10  * GNU General Public License 2.
11  * Please see the COPYING-GPL-2 file for details.
12  */
13
14 #pragma once
15
16 #include <l4/re/c/util/cap_alloc.h>
17 #include <l4/sys/semaphore.h>
18 #include <l4/re/env.h>
19 #include <l4/sys/factory.h>
20 #include <l4/sys/task.h>
21
22 /**
23  * Memory alignment requirement for L4 kernel semaphores.
24  *
25  * Make sure that your memory is aligned to this size when
26  * allocating memory for a kernel semaphore dynamically.
27  */
28 #define USEM_LOCK_ALIGN (2*sizeof(l4_mword_t))
29
30 /**
31  * Allocate memory that is aligned to USEM_LOCK_ALIGN.
32  *
33  * #type must contain a member #baseptrname where the
34  * pointer to the original base is stored.
35  *
36  * \param ptr result pointer
37  * \param type type to be allocated
38  * \param baseptrname name of the base pointer slot
39  *        in type
40  * \param malloc_fn function for allocating memory
41  */
42 #define USEM_ALLOC_ALIGNED(ptr, type, baseptrname, malloc_fn) \
43         do { \
44                 void *_tmp = (malloc_fn)(sizeof(type) + USEM_LOCK_ALIGN); \
45                 long _mask = ~(USEM_LOCK_ALIGN - 1); \
46                 (ptr) = (type *)((char*)_tmp + USEM_LOCK_ALIGN); \
47                 (ptr) = (type *)((long)(ptr) & _mask); \
48                 (ptr)->baseptrname = _tmp; \
49         } while (0);
50
51 L4_INLINE int
52  __do_init_lock(l4_u_semaphore_t *sem, l4_cap_idx_t *cap, int init_val);
53
54 L4_INLINE int
55 __init_lock_locked(l4_u_semaphore_t *sem, l4_cap_idx_t *cap);
56
57 L4_INLINE int
58 __init_lock_unlocked(l4_u_semaphore_t *sem, l4_cap_idx_t *cap);
59
60 L4_INLINE int
61 __lock(l4_u_semaphore_t *sem, l4_cap_idx_t cap);
62
63 L4_INLINE int
64 __lock_timed(l4_u_semaphore_t *sem, l4_cap_idx_t cap, l4_timeout_s to);
65
66 L4_INLINE int
67 __unlock(l4_u_semaphore_t *sem, l4_cap_idx_t cap);
68
69 L4_INLINE int
70 __lock_free(l4_cap_idx_t cap);
71
72 L4_INLINE int
73 __locked(l4_u_semaphore_t *s);
74
75 /**
76  * Initialize u_semaphore.
77  *
78  * \param sem   semaphore ptr
79  * \param cap   cap ptr
80  * \param init_val initial counter value
81  *
82  * \retval cap  semaphore cap
83  * \retval sem  semaphore
84  * \return 1 for success,  0 on error
85  */
86 L4_INLINE int __do_init_lock(l4_u_semaphore_t *sem,
87                              l4_cap_idx_t *cap, int init_val)
88 {
89         *cap = l4re_util_cap_alloc();
90         if (l4_is_invalid_cap(*cap))
91                 return 0;
92
93         l4_msgtag_t ret = l4_factory_create_semaphore(l4re_env()->factory, *cap);
94         if (l4_error(ret))
95                 return 0;
96
97         l4_usem_init(init_val ,sem);
98
99         return 1;
100 }
101
102
103 /**
104  * Initialize u_semaphore in locked state
105  *
106  * \param sem   semaphore ptr
107  * \param cap   cap ptr
108  * \param init_val initial counter value
109  *
110  * \retval cap  semaphore cap
111  * \retval sem  semaphore
112  * \return 1 for success,  0 on error
113  */
114 L4_INLINE int __init_lock_locked(l4_u_semaphore_t *sem,
115                                  l4_cap_idx_t *cap)
116 {
117         return __do_init_lock(sem, cap, 0);
118 }
119
120
121 /**
122  * Initialize u_semaphore in unlocked state
123  *
124  * \param sem   semaphore ptr
125  * \param cap   cap ptr
126  * \param init_val initial counter value
127  *
128  * \retval cap  semaphore cap
129  * \retval sem  semaphore
130  * \return 1 for success,  0 on error
131  */
132 L4_INLINE int __init_lock_unlocked(l4_u_semaphore_t *sem,
133                                    l4_cap_idx_t *cap)
134 {
135         return __do_init_lock(sem, cap, 1);
136 }
137
138
139 /**
140  * Lock u_semaphore.
141  *
142  * \param sem semaphore
143  * \param cap semaphore cap
144  *
145  * \return 1 success, 0 error
146  */
147 L4_INLINE int __lock(l4_u_semaphore_t *sem, l4_cap_idx_t cap)
148 {
149         return (l4_usem_down(cap, sem).raw == L4_USEM_OK);
150 }
151
152
153 /**
154  * Lock u_semaphore with timeout.
155  *
156  * \param sem semaphore
157  * \param cap semaphore cap
158  * \param to  timeout
159  * \return 1 success, 0 error
160  */
161 L4_INLINE int __lock_timed(l4_u_semaphore_t *sem,
162                            l4_cap_idx_t cap, l4_timeout_s to)
163 {
164         return (l4_usem_down_to(cap, sem, to).raw == L4_USEM_OK);
165 }
166
167
168 /**
169  * Unlock u_semaphore.
170  *
171  * \param sem semaphore
172  * \param cap semaphore cap
173  *
174  * \return 1 success, 0 error
175  */
176 L4_INLINE int __unlock(l4_u_semaphore_t *sem, l4_cap_idx_t cap)
177 {
178         return (l4_usem_up(cap, sem).raw == L4_USEM_OK);
179 }
180
181
182 /**
183  * Delete u_semaphore.
184  *
185  * \param cap semaphore cap
186  *
187  * \return 1 success, 0 error
188  */
189 L4_INLINE int __lock_free(l4_cap_idx_t cap)
190 {
191   l4_msgtag_t ret = l4_task_unmap(L4RE_THIS_TASK_CAP,
192                                   l4_obj_fpage(cap, 0, L4_FPAGE_RWX),
193                                   L4_FP_ALL_SPACES);
194
195   l4re_util_cap_free(cap);
196
197   return !l4_msgtag_has_error(ret);
198 }
199
200
201 /*
202  * Determine whether a usem is locked.
203  *
204  * \param s u_semaphore to check.
205  * \return 1 if locked, 0 if not
206  */
207 L4_INLINE int __locked(l4_u_semaphore_t *s)
208 {
209   return (s->counter < 1);
210 }