IntrOS
Loading...
Searching...
No Matches
osconditionvariable.h
1/******************************************************************************
2
3 @file IntrOS: osconditionvariable.h
4 @author Rajmund Szymanski
5 @date 17.11.2025
6 @brief This file contains definitions for IntrOS.
7
8 ******************************************************************************
9
10 Copyright (c) 2018-2022 Rajmund Szymanski. All rights reserved.
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to
14 deal in the Software without restriction, including without limitation the
15 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 sell copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 IN THE SOFTWARE.
29
30 ******************************************************************************/
31
32#ifndef __INTROS_CND_H
33#define __INTROS_CND_H
34
35#include "oskernel.h"
36#include "osclock.h"
37#include "osmutex.h"
38
44
45/* -------------------------------------------------------------------------- */
46
47#define cndOne ( false )
48#define cndAll ( true )
49
53
54typedef struct __cnd cnd_t;
55
56struct __cnd
57{
58 obj_t obj;
59};
60
61typedef struct __cnd cnd_id [];
62
63/******************************************************************************
64 *
65 * Name : _CND_INIT
66 *
67 * Description : create and initialize a condition variable object
68 *
69 * Parameters : none
70 *
71 * Return : condition variable object
72 *
73 * Note : for internal use
74 *
75 ******************************************************************************/
76
77#define _CND_INIT() { _OBJ_INIT() }
78
85#define OS_CND( cnd ) \
86 cnd_t cnd[] = { _CND_INIT() }
87
88/** static alias of OS_CND() */
89#define static_CND( cnd ) \
90 static cnd_t cnd[] = { _CND_INIT() }
91
99
100#ifndef __cplusplus
101#define CND_INIT() \
102 _CND_INIT()
103#endif
104
112
113#ifndef __cplusplus
114#define CND_CREATE() \
115 { CND_INIT () }
116/** alias of CND_CREATE() */
117#define CND_NEW \
118 CND_CREATE
119#endif
120
121#ifdef __cplusplus
122extern "C" {
123#endif
124
131void cnd_init( cnd_t *cnd );
132
141void cnd_reset( cnd_t *cnd );
142
144__STATIC_INLINE
145void cnd_kill( cnd_t *cnd ) { cnd_reset(cnd); }
146
163int cnd_waitFor( cnd_t *cnd, mtx_t *mtx, cnt_t delay );
164
179int cnd_waitUntil( cnd_t *cnd, mtx_t *mtx, cnt_t time );
180
194
195__STATIC_INLINE
196int cnd_wait( cnd_t *cnd, mtx_t *mtx ) { return cnd_waitFor(cnd, mtx, INFINITE); }
197
207void cnd_give( cnd_t *cnd, bool all );
208
216
217__STATIC_INLINE
218void cnd_notifyOne( cnd_t *cnd ) { cnd_give(cnd, cndOne); }
219
227
228__STATIC_INLINE
229void cnd_notifyAll( cnd_t *cnd ) { cnd_give(cnd, cndAll); }
230
231#ifdef __cplusplus
232}
233#endif
234
235/* -------------------------------------------------------------------------- */
236
237#if defined(__cplusplus)
238namespace intros {
239
244struct ConditionVariable : public __cnd
245{
247 constexpr
248 ConditionVariable(): __cnd _CND_INIT() {}
249
250 ~ConditionVariable() { assert(__cnd::obj.queue == nullptr); }
251
252 /// move constructor
253 ConditionVariable( ConditionVariable&& _src ): __cnd(_src)
254 {
255 assert(_src.obj.queue == nullptr);
256 }
257
258 ConditionVariable( const ConditionVariable& ) = delete;
259 ConditionVariable& operator=( ConditionVariable&& ) = delete;
260 ConditionVariable& operator=( const ConditionVariable& ) = delete;
262 void reset () { cnd_reset (this); }
263 void kill () { cnd_kill (this); }
264 template<typename T>
265 int waitFor ( mtx_t& _mtx, const T& _delay ) { return cnd_waitFor (this, &_mtx, Clock::count(_delay)); }
266 template<typename T>
267 int waitUntil( mtx_t& _mtx, const T& _time ) { return cnd_waitUntil(this, &_mtx, Clock::until(_time)); }
268 int wait ( mtx_t& _mtx ) { return cnd_wait (this, &_mtx); }
269 void give ( bool _all = cndAll ) { cnd_give (this, _all); }
270 void notifyOne() { cnd_notifyOne(this); }
271 void notifyAll() { cnd_notifyAll(this); }
273 template<typename T, typename F>
274 int waitFor ( mtx_t& _mtx, const T& _delay, F _stopWaiting )
275 {
276 auto _time = Clock::count(_delay);
277 return (_time == INFINITE) ? wait(_mtx, _stopWaiting)
278 : waitUntil(_mtx, sys_time() + _time, _stopWaiting);
279 }
281 template<typename T, typename F>
282 int waitUntil( mtx_t& _mtx, const T& _time, F _stopWaiting )
283 {
284 int result = E_SUCCESS;
285 while (!_stopWaiting() && (result = waitUntil(_mtx, _time)) == E_SUCCESS);
286 if (result == E_TIMEOUT && _stopWaiting()) // the mutex is held again, the condition may have been satisfied during the timeout
287 result = E_SUCCESS;
288 return result;
289 }
291 template<typename F>
292 int wait ( mtx_t& _mtx, F _stopWaiting )
293 {
294 int result = E_SUCCESS;
295 while (!_stopWaiting() && (result = wait(_mtx)) == E_SUCCESS);
296 return result;
297 }
298};
299
300} // namespace
301#endif//__cplusplus
302
303/* -------------------------------------------------------------------------- */
304
306
307#endif//__INTROS_CND_H
#define INFINITE
infinite waiting
Definition osbase.h:250
@ E_TIMEOUT
process was released as a result of the end of the timer countdown
Definition osbase.h:153
@ E_SUCCESS
process was released as a result of taking the supervising object
Definition osbase.h:150
cnt_t sys_time(void)
return current value of system counter
void cnd_notifyAll(cnd_t *cnd)
signal all tasks waiting on the condition variable
Definition osconditionvariable.h:228
int cnd_wait(cnd_t *cnd, mtx_t *mtx)
wait indefinitely on the condition variable releasing the currently owned mutex, and finally lock the...
Definition osconditionvariable.h:195
void cnd_init(cnd_t *cnd)
initialize a condition variable object
void cnd_reset(cnd_t *cnd)
reset the condition variable object and wake up all waiting tasks with 'E_STOPPED' event value
#define cndAll
notify all tasks (broadcast)
Definition osconditionvariable.h:48
void cnd_kill(cnd_t *cnd)
alias of cnd_reset()
Definition osconditionvariable.h:144
void cnd_notifyOne(cnd_t *cnd)
signal one task waiting on the condition variable
Definition osconditionvariable.h:217
int cnd_waitUntil(cnd_t *cnd, mtx_t *mtx, cnt_t time)
wait until given timepoint on the condition variable releasing the currently owned mutex,...
int cnd_waitFor(cnd_t *cnd, mtx_t *mtx, cnt_t delay)
wait for given duration of time on the condition variable releasing the currently owned mutex,...
void cnd_give(cnd_t *cnd, bool all)
signal one or all tasks that are waiting on the condition variable
#define cndOne
notify one task
Definition osconditionvariable.h:47
static constexpr rep until(const std::chrono::time_point< Clock, _Duration > &_time)
time point in ticks, rounded up to whole ticks (only a time point of this clock)
Definition osclock.h:109
static constexpr rep count(const std::chrono::duration< _Rep, _Period > &_delay)
delay in ticks, rounded up to whole ticks; negative delay: IMMEDIATE, delay out of range: INFINITE
Definition osclock.h:102
create and initialize a condition variable object
Definition osconditionvariable.h:244
void give(bool _all=cndAll)
cnd_give()
Definition osconditionvariable.h:268
void notifyAll()
cnd_notifyAll()
Definition osconditionvariable.h:270
int waitUntil(mtx_t &_mtx, const T &_time)
cnd_waitUntil()
Definition osconditionvariable.h:266
void reset()
cnd_reset()
Definition osconditionvariable.h:261
void notifyOne()
cnd_notifyOne()
Definition osconditionvariable.h:269
constexpr ConditionVariable()
constructor, see the constructor parameters of the class
Definition osconditionvariable.h:247
int waitFor(mtx_t &_mtx, const T &_delay)
cnd_waitFor()
Definition osconditionvariable.h:264
int wait(mtx_t &_mtx)
cnd_wait()
Definition osconditionvariable.h:267
void kill()
cnd_kill()
Definition osconditionvariable.h:262