4 * \brief User-Level Semaphores.
8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9 * Alexander Warg <warg@os.inf.tu-dresden.de>
10 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction. Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License. This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
28 #include <l4/sys/semaphore.h>
29 #include <l4/sys/capability>
35 * \brief Kernel pert of the fast user semaphore.
37 * <c>\#include <l4/sys/semaphore></c>
39 * \see L4::Semaphore for the full sempahore class.
41 class K_semaphore : public Kobject
48 * \brief return codes of the down operation.
52 OK = 0, ///< Got the semaphore.
53 TIMEOUT = 2, ///< Timeout during blocking.
54 INVALID = 3 ///< The semaphore does not exist, or is about to be deleted.
57 long down(l4_u_semaphore_t *sem, l4_timeout_s timeout) throw()
58 { return l4_error(l4_usem_down_to(cap(), sem, timeout)); }
59 long down(l4_u_semaphore_t *sem) throw()
60 { return l4_error(l4_usem_down(cap(), sem)); }
61 long up(l4_u_semaphore_t *sem) throw()
62 { return l4_error(l4_usem_up(cap(), sem)); }
67 * \brief Fast user-level semaphore.
69 * <c>\#include <l4/sys/semaphore></c>
71 * This is a fast user-level semaphore implementation. It can be used
72 * for all kinds of synchronization and is well optimized for the
73 * non-contention case.
83 * \brief Return codes for the down operations.
87 OK = K_semaphore::OK, ///< Got the semaphore.
88 TIMEOUT = K_semaphore::TIMEOUT, ///< Timeout during blocking.
89 INVALID = K_semaphore::INVALID, ///< Semaphore does not exist, or is about to be deleted.
94 * \brief Create a new semaphore.
95 * \param k the capability selector for the kernel part of the semaphore.
97 * The kernel part must be allocated separately (see L4::Factory,
98 * \ref l4_factory_api). You can also initialize the capability and
99 * the counter value later by using one of the init() methods.
101 Semaphore(Cap<K_semaphore> const &k = Cap<K_semaphore>::Invalid) : _k(k)
102 { _u.counter = 0; _u.flags = 0; }
105 * \brief Initialize the semaphore object.
106 * \param cnt the initial counter value (>0 means free, <=0 means blocked).
107 * \param k the capability for the kernel object related to that semaphore.
109 void init(long cnt, Cap<K_semaphore> const &k)
110 { _k = k; _u.counter = cnt; _u.flags = 0; }
113 * \brief Initialize the semaphore object.
114 * \param cnt the initial counter value (>0 means free, <=0 means blocked).
117 { _u.counter = cnt; _u.flags = 0; }
120 * \brief Do a down operation on the semaphore, with a timeout for blocking.
121 * \param timeout the timeout to use when the operation blocks.
122 * \return #OK on success, #TIMEOUT or #INVALID on failure.
124 * \note This operation will block if the counter is 0 or less.
125 * \note To implement a try-lock semantics use a relative timeout of 0, this
126 * shall immediately return in either case and the return value
127 * indicates if the operation succeeded.
129 long down(l4_timeout_s timeout) throw()
130 { return _k->down(&_u, timeout); }
133 * \brief Do a down operation on the semaphore.
134 * \return #OK on success, #INVALID on failure.
136 * \note This operation will block if the counter is 0 or less.
139 { return _k->down(&_u); }
142 * \brief Do an up operation on the semaphore.
144 * \note This operation shall wakeup possibly blocked threads.
147 { return _k->up(&_u); }
150 * \brief Get the capability for the kernel part.
152 Cap<K_semaphore> ksem_cap() const { return _k; }