L4Re - L4 Runtime Environment
semaphore
Go to the documentation of this file.
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /**
3  * \file
4  * Semaphore class definition.
5  */
6 /*
7  * (c) 2015 Alexander Warg <alexander.warg@kernkonzept.com>
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  * As a special exception, you may use this file as part of a free software
14  * library without restriction. Specifically, if other files instantiate
15  * templates or use macros or inline functions from this file, or you compile
16  * this file and link it with other files to produce an executable, this
17  * file does not by itself cause the resulting executable to be covered by
18  * the GNU General Public License. This exception does not however
19  * invalidate any other reasons why the executable file might be covered by
20  * the GNU General Public License.
21  */
22 
23 #pragma once
24 
25 #include <l4/sys/irq>
26 #include <l4/sys/semaphore.h>
27 
28 namespace L4 {
29 
30 /**
31  * Kernel-provided semaphore object.
32  *
33  * This is the interface for kernel-provided semaphore objects. The
34  * object provides the classical functions `up()` and `down()` for
35  * counting the semaphore and blocking. The semaphore is a
36  * Triggerable with respect to the `up()` function, this means that a
37  * semaphore can be bound to an interrupt line at an ICU (L4::Icu) and
38  * incoming interrupts increment the semaphore counter.
39  *
40  * The `down()` method decrements the semaphore counter and blocks
41  * if the counter is already zero. Blocking on a semaphore may---as all
42  * blocking operations---either return successfully, or be aborted due to
43  * an expired timeout provided to the `down()` operation, or due to an
44  * L4::Thread::ex_regs() operation with the #L4_THREAD_EX_REGS_CANCEL
45  * flag set.
46  *
47  * The main reason for using a semaphore instead of an L4::Irq is to ensure
48  * that incoming trigger signals do not interfere with any open-wait
49  * operations, as used for example in a server loop.
50  */
51 struct Semaphore : Kobject_t<Semaphore, Triggerable, L4_PROTO_SEMAPHORE>
52 {
53  /**
54  * Semaphore up operation (wrapper for trigger()).
55  *
56  * \utcb{utcb}
57  *
58  * \return Send-only IPC message return tag. Use l4_ipc_error() to check for
59  * errors, do **not** use l4_error().
60  *
61  * Increases the semaphore counter by one if it is smaller than an
62  * unspecified limit. The unspecified limit is guaranteed to be at
63  * least 2^31-1.
64  */
65  l4_msgtag_t up(l4_utcb_t *utcb = l4_utcb()) throw()
66  { return trigger(utcb); }
67 
68  /**
69  * Semaphore down operation.
70  *
71  * \param timeout Timeout for blocking the semaphore down operation.
72  * Note: The receive timeout of this timeout-pair is
73  * significant for blocking, the send part is usually
74  * non-blocking.
75  * \utcb{utcb}
76  *
77  * \return IPC message return tag. Use l4_ipc_error() to check for
78  * a timeout or a cancel condition.
79  *
80  * This method decrements the semaphore counter by one, or blocks if the
81  * counter is already zero, until either a timeout or cancel condition hits
82  * or the counter is increased by an `up()` operation.
83  */
84  l4_msgtag_t down(l4_timeout_t timeout = L4_IPC_NEVER,
85  l4_utcb_t *utcb = l4_utcb()) throw()
86  { return l4_semaphore_down_u(cap(), timeout, utcb); }
87 };
88 
89 }