2 * This file is part of DDEKit.
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)
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.
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>
23 * Memory alignment requirement for L4 kernel semaphores.
25 * Make sure that your memory is aligned to this size when
26 * allocating memory for a kernel semaphore dynamically.
28 #define USEM_LOCK_ALIGN (2*sizeof(l4_mword_t))
31 * Allocate memory that is aligned to USEM_LOCK_ALIGN.
33 * #type must contain a member #baseptrname where the
34 * pointer to the original base is stored.
36 * \param ptr result pointer
37 * \param type type to be allocated
38 * \param baseptrname name of the base pointer slot
40 * \param malloc_fn function for allocating memory
42 #define USEM_ALLOC_ALIGNED(ptr, type, baseptrname, malloc_fn) \
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; \
52 __do_init_lock(l4_u_semaphore_t *sem, l4_cap_idx_t *cap, int init_val);
55 __init_lock_locked(l4_u_semaphore_t *sem, l4_cap_idx_t *cap);
58 __init_lock_unlocked(l4_u_semaphore_t *sem, l4_cap_idx_t *cap);
61 __lock(l4_u_semaphore_t *sem, l4_cap_idx_t cap);
64 __lock_timed(l4_u_semaphore_t *sem, l4_cap_idx_t cap, l4_timeout_s to);
67 __unlock(l4_u_semaphore_t *sem, l4_cap_idx_t cap);
70 __lock_free(l4_cap_idx_t cap);
73 __locked(l4_u_semaphore_t *s);
76 * Initialize u_semaphore.
78 * \param sem semaphore ptr
80 * \param init_val initial counter value
82 * \retval cap semaphore cap
83 * \retval sem semaphore
84 * \return 1 for success, 0 on error
86 L4_INLINE int __do_init_lock(l4_u_semaphore_t *sem,
87 l4_cap_idx_t *cap, int init_val)
89 *cap = l4re_util_cap_alloc();
90 if (l4_is_invalid_cap(*cap))
93 l4_msgtag_t ret = l4_factory_create_semaphore(l4re_env()->factory, *cap);
97 l4_usem_init(init_val ,sem);
104 * Initialize u_semaphore in locked state
106 * \param sem semaphore ptr
108 * \param init_val initial counter value
110 * \retval cap semaphore cap
111 * \retval sem semaphore
112 * \return 1 for success, 0 on error
114 L4_INLINE int __init_lock_locked(l4_u_semaphore_t *sem,
117 return __do_init_lock(sem, cap, 0);
122 * Initialize u_semaphore in unlocked state
124 * \param sem semaphore ptr
126 * \param init_val initial counter value
128 * \retval cap semaphore cap
129 * \retval sem semaphore
130 * \return 1 for success, 0 on error
132 L4_INLINE int __init_lock_unlocked(l4_u_semaphore_t *sem,
135 return __do_init_lock(sem, cap, 1);
142 * \param sem semaphore
143 * \param cap semaphore cap
145 * \return 1 success, 0 error
147 L4_INLINE int __lock(l4_u_semaphore_t *sem, l4_cap_idx_t cap)
149 return (l4_usem_down(cap, sem).raw == L4_USEM_OK);
154 * Lock u_semaphore with timeout.
156 * \param sem semaphore
157 * \param cap semaphore cap
159 * \return 1 success, 0 error
161 L4_INLINE int __lock_timed(l4_u_semaphore_t *sem,
162 l4_cap_idx_t cap, l4_timeout_s to)
164 return (l4_usem_down_to(cap, sem, to).raw == L4_USEM_OK);
169 * Unlock u_semaphore.
171 * \param sem semaphore
172 * \param cap semaphore cap
174 * \return 1 success, 0 error
176 L4_INLINE int __unlock(l4_u_semaphore_t *sem, l4_cap_idx_t cap)
178 return (l4_usem_up(cap, sem).raw == L4_USEM_OK);
183 * Delete u_semaphore.
185 * \param cap semaphore cap
187 * \return 1 success, 0 error
189 L4_INLINE int __lock_free(l4_cap_idx_t cap)
191 l4_msgtag_t ret = l4_task_unmap(L4RE_THIS_TASK_CAP,
192 l4_obj_fpage(cap, 0, L4_FPAGE_RWX),
195 l4re_util_cap_free(cap);
197 return !l4_msgtag_has_error(ret);
202 * Determine whether a usem is locked.
204 * \param s u_semaphore to check.
205 * \return 1 if locked, 0 if not
207 L4_INLINE int __locked(l4_u_semaphore_t *s)
209 return (s->counter < 1);