IntrOS
Toggle main menu visibility
Loading...
Searching...
No Matches
osonceflag.h
1
/******************************************************************************
2
3
@file IntrOS: osonceflag.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_ONE_H
33
#define __INTROS_ONE_H
34
35
#include "oskernel.h"
36
#include "oscriticalsection.h"
37
43
47
48
typedef
uint_fast8_t
one_t
;
49
typedef
uint_fast8_t one_id [];
50
51
/******************************************************************************
52
*
53
* Name : _ONE_INIT
54
*
55
* Description : once flag state after initialization
56
*
57
* Parameters : none
58
*
59
* Return : once flag object
60
*
61
* Note : for internal use
62
*
63
******************************************************************************/
64
65
#define _ONE_INIT() 0
66
67
/******************************************************************************
68
*
69
* Name : _ONE_DONE
70
*
71
* Description : once flag state after use
72
*
73
* Parameters : none
74
*
75
* Return : once flag object
76
*
77
* Note : for internal use
78
*
79
******************************************************************************/
80
81
#define _ONE_DONE() 1
82
88
89
#define OS_ONE( one ) \
90
one_t one[] = { _ONE_INIT() }
91
92
/** static alias of OS_ONE() */
93
#define static_ONE( one ) \
94
static one_t one[] = { _ONE_INIT() }
95
103
104
#ifndef __cplusplus
105
#define ONE_INIT() \
106
_ONE_INIT()
107
#endif
108
116
117
#ifndef __cplusplus
118
#define ONE_CREATE() \
119
{ ONE_INIT () }
120
/** alias of ONE_CREATE() */
121
#define ONE_NEW \
122
ONE_CREATE
123
#endif
124
125
#ifdef __cplusplus
126
extern
"C"
{
127
#endif
128
134
135
__STATIC_INLINE
136
void
one_init
(
one_t
*one ) { *one = 0; }
137
150
151
__STATIC_INLINE
152
void
one_call
(
one_t
*one,
fun_t
*fun )
153
{
154
one_t
flag;
155
assert(one);
156
assert(fun);
157
#if OS_ATOMICS
158
flag = __STD atomic_exchange((__STD atomic_uint_fast8_t *)one, _ONE_DONE());
159
#else
160
sys_lock
(); flag = *one; *one = _ONE_DONE();
sys_unlock
();
161
#endif
162
if
(flag == _ONE_INIT()) fun();
163
}
164
165
#ifdef __cplusplus
166
}
167
#endif
168
169
/* -------------------------------------------------------------------------- */
170
171
#if defined(__cplusplus)
172
namespace
intros {
173
181
182
struct
OnceFlag
183
{
185
constexpr
186
OnceFlag
(): flg_{_ONE_INIT()} {}
187
189
OnceFlag
(
OnceFlag
&& ) =
default
;
190
OnceFlag
(
const
OnceFlag
& ) =
delete
;
191
OnceFlag
& operator=(
OnceFlag
&& ) =
delete
;
192
OnceFlag
& operator=(
const
OnceFlag
& ) =
delete
;
193
194
#if __cplusplus >= 201402L
196
template
<
typename
Callable,
typename
... Args>
197
void
call
( Callable&& _fun, Args&&... _args )
198
{
199
one_t
flag;
200
#if OS_ATOMICS
201
flag = std::atomic_exchange((std::atomic_uint_fast8_t *)&flg_, _ONE_DONE());
202
#else
203
{
CriticalSection
cri; flag = flg_; flg_ = _ONE_DONE(); }
204
#endif
205
if
(flag == _ONE_INIT()) _fun(std::forward<Args>(_args)...);
206
}
207
#else
208
void
call
(
fun_t
*_fun )
209
{
210
one_call
(&flg_, _fun);
211
}
212
#endif
213
214
private
:
215
one_t
flg_;
216
};
217
218
}
// namespace
219
#endif
//__cplusplus
220
221
/* -------------------------------------------------------------------------- */
222
224
225
#endif
//__INTROS_ONE_H
fun_t
void fun_t(void)
timer/task procedure
Definition
osbase.h:142
sys_unlock
#define sys_unlock()
restore saved interrupts state / exit from critical section
Definition
oscriticalsection.h:148
sys_lock
#define sys_lock()
save interrupts state then disable interrupts / enter into critical section
Definition
oscriticalsection.h:140
one_init
void one_init(one_t *one)
initialize a once flag object
Definition
osonceflag.h:135
one_call
void one_call(one_t *one, fun_t *fun)
try to execute given function
Definition
osonceflag.h:151
one_t
uint_fast8_t one_t
once flag
Definition
osonceflag.h:48
intros::CriticalSection
create and initialize a critical section guard object
Definition
oscriticalsection.h:165
intros::OnceFlag::OnceFlag
constexpr OnceFlag()
constructor, see the constructor parameters of the class
Definition
osonceflag.h:185
intros::OnceFlag::call
void call(Callable &&_fun, Args &&... _args)
call _fun(_args...) once, like std::call_once (one_call())
Definition
osonceflag.h:196
kernel
inc
osonceflag.h
Generated by
1.18.0