]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/semaphore
update
[l4.git] / l4 / pkg / l4sys / include / semaphore
1 // vi:ft=cpp
2 /*
3  * \file
4  * \brief   User-Level Semaphores.
5  * \ingroup l4_sem_api
6  */
7 /*
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)
11  *
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.
15  *
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.
24  */
25
26 #pragma once
27
28 #include <l4/sys/semaphore.h>
29 #include <l4/sys/capability>
30
31 namespace L4 {
32
33 /*
34  * \ingroup l4_sem_api
35  * \brief Kernel pert of the fast user semaphore.
36  *
37  * <c>\#include <l4/sys/semaphore></c>
38  *
39  * \see L4::Semaphore for the full sempahore class.
40  */
41 class K_semaphore : public Kobject
42 {
43 protected:
44   K_semaphore();
45
46 public:
47   /*
48    * \brief return codes of the down operation.
49    */
50   enum Returncode
51   {
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.
55   };
56
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)); }
63 };
64
65 /*
66  * \ingroup l4_sem_api
67  * \brief Fast user-level semaphore.
68  * 
69  * <c>\#include <l4/sys/semaphore></c>
70  * 
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.
74  */
75 class Semaphore
76 {
77 private:
78   l4_u_semaphore_t _u;
79   Cap<K_semaphore> _k;
80
81 public:
82   /*
83    * \brief Return codes for the down operations.
84    */
85   enum Returncode
86   {
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.
90   };
91
92
93   /*
94    * \brief Create a new semaphore.
95    * \param k the capability selector for the kernel part of the semaphore.
96    *
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.
100    */
101   Semaphore(Cap<K_semaphore> const &k = Cap<K_semaphore>::Invalid) : _k(k)
102   { _u.counter = 0; _u.flags = 0; }
103
104   /*
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.
108    */
109   void init(long cnt, Cap<K_semaphore> const &k)
110   { _k = k; _u.counter = cnt; _u.flags = 0; }
111
112   /*
113    * \brief Initialize the semaphore object.
114    * \param cnt the initial counter value (>0 means free, <=0 means blocked).
115    */
116   void init(long cnt)
117   { _u.counter = cnt; _u.flags = 0; }
118
119   /*
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.
123    *
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.
128    */
129   long down(l4_timeout_s timeout) throw()
130   { return _k->down(&_u, timeout); }
131
132   /*
133    * \brief Do a down operation on the semaphore.
134    * \return #OK on success, #INVALID on failure.
135    *
136    * \note This operation will block if the counter is 0 or less.
137    */
138   long down() throw()
139   { return _k->down(&_u); }
140
141   /*
142    * \brief Do an up operation on the semaphore.
143    *
144    * \note This operation shall wakeup possibly blocked threads.
145    */
146   long up() throw()
147   { return _k->up(&_u); }
148
149   /*
150    * \brief Get the capability for the kernel part.
151    */
152   Cap<K_semaphore> ksem_cap() const { return _k; }
153 };
154
155 }