Skip to content

Commit 78230ec

Browse files
committed
upd
1 parent 999a517 commit 78230ec

File tree

4 files changed

+64
-43
lines changed

4 files changed

+64
-43
lines changed

docs/0.main.md

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,12 @@ LP_TICKER_(id, func)
3939
// создать статический таймер
4040
LP_TIMER(ms, func)
4141
LP_TIMER_(id, ms, func)
42-
```
4342

44-
### Макросы потоков
45-
```cpp
4643
// создать статический поток
4744
LP_THREAD(body)
4845
LP_THREAD_(id, body)
4946
LP_THREAD_DATA(T, data, data_arg, body)
5047
LP_THREAD_DATA_(id, T, data, data_arg, body)
51-
52-
// начало и конец потока для создания вручную
53-
LP_THREAD_BEGIN()
54-
LP_THREAD_END()
55-
56-
// асинхронно ждать события в потоке
57-
LP_WAIT_EVENT(cond)
58-
59-
// асинхронно ждать условия в потоке
60-
LP_WAIT(cond)
61-
62-
// асинхронно ждать время в мс в потоке
63-
LP_DELAY(ms)
64-
65-
// выйти из потока и потом вернуться в эту точку
66-
LP_EXIT()
67-
68-
// освободить семафор
69-
LP_SEM_SIGNAL(sem)
70-
71-
// ждать семафор
72-
LP_SEM_WAIT(sem)
7348
```
7449
7550
### `Looper`

docs/2.threads.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,34 @@ LP_THREAD_("thread_id", {
2525

2626
> Внутри обработчика точно так же можно обращаться к задаче через `thisTask` и делать всё то же самое, что с `LoopTicker` (остановить, исключить из loop, отправить-поймать событие и так далее).
2727
28-
Для управления потоком используются специальные макросы.
28+
Для управления потоком используются специальные управляющие макросы:
29+
30+
```cpp
31+
// начало и конец потока для создания вручную
32+
LP_THREAD_BEGIN()
33+
LP_THREAD_END()
34+
35+
// перезапустить поток (начать выполнение с начала)
36+
LP_RESTART()
37+
38+
// выйти из потока и потом вернуться в эту точку
39+
LP_EXIT()
40+
41+
// асинхронно ждать время в потоке, мс
42+
LP_DELAY(ms)
43+
44+
// асинхронно ждать условия в потоке
45+
LP_WAIT(cond)
46+
47+
// асинхронно ждать Looper-события в потоке
48+
LP_WAIT_EVENT()
49+
50+
// ждать семафор
51+
LP_SEM_WAIT(sem)
52+
53+
// освободить семафор
54+
LP_SEM_SIGNAL(sem)
55+
```
2956
3057
### Выход из потока
3158
В любой момент можно покинуть поток и отдать выполнение другим потокам, на следующем круге диспетчера задач управление вернётся к потоку и продолжится после точки выхода. Полезно например если нужно "размазать" какие то долгие сложные вычисления по времени и выполнять в промежутках другие потоки:
@@ -114,10 +141,11 @@ LP_TIMER(1000, []() {
114141
```
115142
116143
## Ограничения
117-
Реализация потоков очень простая и лёгкая, поэтому есть ограничения. По сути все макросы ожидания создают метку перехода, а весь код находится внутри `switch`, это означает что:
144+
Реализация потоков очень простая и лёгкая, поэтому есть ограничения. По сути все управляющие макросы создают метку перехода, а весь код находится внутри `switch`, это означает что:
118145
- После макроса ожидания будет выход из функции без сохранения стека, т.е. объявленные выше локальные переменные потеряют значения
119-
- Нельзя создавать внутри потока локальные переменные, которые "живут" между вызовами макросов ожидания
146+
- Нельзя создавать внутри потока локальные переменные, которые "живут" между вызовами управляющих макросов
120147
- Для создания "стека" используем статические переменные внутри функции
148+
- Нельзя использовать управляющие макросы внутри `switch`
121149
122150
Например цикл с задержкой делать вот так **нельзя**:
123151
```cpp

library.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=Looper
2-
version=1.1.2
2+
version=1.1.3
33
author=AlexGyver <[email protected]>
44
maintainer=AlexGyver <[email protected]>
5-
sentence=Simple task and event manager for Arduino
6-
paragraph=Simple task and event manager for Arduino
5+
sentence=Simple task, thread and event manager for Arduino
6+
paragraph=Simple task, thread and event manager for Arduino
77
category=Control
88
url=https://github.com/GyverLibs/Looper
99
architectures=*

src/Looper.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,36 +33,54 @@
3333
#define LP_TIMER_(id, ms, func) LP_MAKE_(id, LoopTimer, ms, func)
3434

3535
// THREAD
36-
#define LP_THREAD_BEGIN() \
37-
switch (Looper.thisThread()->_case) { \
36+
#define _LP_THREAD_CASE Looper.thisThread()->_case
37+
#define _LP_THREAD_RESET() _LP_THREAD_CASE = 0;
38+
39+
// начать поток
40+
#define LP_THREAD_BEGIN() \
41+
switch (_LP_THREAD_CASE) { \
3842
case 0:;
3943

44+
// завершить поток
4045
#define LP_THREAD_END() \
4146
} \
42-
Looper.thisThread()->_case = 0;
47+
_LP_THREAD_RESET();
4348

4449
#define _LP_THREAD_INNER(body) \
4550
LP_THREAD_BEGIN(); \
46-
body; \
51+
body \
4752
LP_THREAD_END();
4853

4954
#define LP_THREAD(body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)([]() { _LP_THREAD_INNER(body) })
5055
#define LP_THREAD_(id, body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), []() { _LP_THREAD_INNER(body) })
5156
#define LP_THREAD_DATA(T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(data, [](data_arg) { _LP_THREAD_INNER(body) })
5257
#define LP_THREAD_DATA_(id, T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), data, [](data_arg) { _LP_THREAD_INNER(body) })
5358

59+
// перезапустить поток (начать выполнение с начала)
60+
#define LP_RESTART() \
61+
do { \
62+
_LP_THREAD_RESET(); \
63+
return; \
64+
} while (0);
65+
5466
// выйти из потока и потом вернуться в эту точку
55-
#define LP_EXIT() \
56-
Looper.thisThread()->_case = __COUNTER__ + 1; \
57-
case __COUNTER__:
67+
#define LP_EXIT() \
68+
do { \
69+
_LP_THREAD_CASE = __COUNTER__ + 1; \
70+
return; \
71+
case __COUNTER__:; \
72+
} while (0);
5873

5974
// асинхронно ждать условия
60-
#define LP_WAIT(cond) \
61-
LP_EXIT(); \
62-
if (!(cond)) return;
75+
#define LP_WAIT(cond) \
76+
do { \
77+
_LP_THREAD_CASE = __COUNTER__ + 1; \
78+
case __COUNTER__: \
79+
if (!(cond)) return; \
80+
} while (0);
6381

6482
// асинхронно ждать события
65-
#define LP_WAIT_EVENT(cond) LP_WAIT(Looper.thisEvent());
83+
#define LP_WAIT_EVENT() LP_WAIT(Looper.thisEvent());
6684

6785
// асинхронно ждать время в мс
6886
#define LP_DELAY(ms) \
@@ -86,4 +104,4 @@
86104
} while (0);
87105

88106
// семафор
89-
typedef uint8_t LP_SEM;
107+
typedef uint16_t LP_SEM;

0 commit comments

Comments
 (0)