Skip to content

Commit 48bd0e4

Browse files
authored
[ipc] support of lockless rt_completion (#8887)
* [ipc] lockless rt_completion implementation The new rt_completion implemented by lockless algorithm can improve timer resolution for up to ~12%, compare to sem IPC. Signed-off-by: Shell <[email protected]> * fixup: error * remove useless changes --------- Signed-off-by: Shell <[email protected]>
1 parent 9ba6cec commit 48bd0e4

File tree

17 files changed

+967
-90
lines changed

17 files changed

+967
-90
lines changed

components/drivers/Kconfig

+1-24
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,7 @@ config RT_USING_DM
77
Enable device driver model with device tree (FDT). It will use more memory
88
to parse and support device tree feature.
99

10-
config RT_USING_DEVICE_IPC
11-
bool "Using device drivers IPC"
12-
default y
13-
14-
config RT_UNAMED_PIPE_NUMBER
15-
int "The number of unamed pipe"
16-
depends on RT_USING_DEVICE_IPC
17-
default 64
18-
19-
if RT_USING_DEVICE_IPC
20-
config RT_USING_SYSTEM_WORKQUEUE
21-
bool "Using system default workqueue"
22-
default n
23-
24-
if RT_USING_SYSTEM_WORKQUEUE
25-
config RT_SYSTEM_WORKQUEUE_STACKSIZE
26-
int "The stack size for system workqueue thread"
27-
default 2048
28-
29-
config RT_SYSTEM_WORKQUEUE_PRIORITY
30-
int "The priority level of system workqueue thread"
31-
default 23
32-
endif
33-
endif
10+
source "$RTT_DIR/components/drivers/ipc/Kconfig"
3411

3512
menuconfig RT_USING_SERIAL
3613
bool "USING Serial device drivers"

components/drivers/include/ipc/completion.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*
66
* Change Logs:
77
* Date Author Notes
8+
* 2024-04-28 Shell Add new wait_flags() & wakeup_by_errno() API
89
*/
910
#ifndef COMPLETION_H_
1011
#define COMPLETION_H_
@@ -13,7 +14,7 @@
1314
#include <rtconfig.h>
1415

1516
/**
16-
* Completion - A tiny IPC implementation for resource-constrained scenarios
17+
* Completion - A tiny & rapid IPC primitive for resource-constrained scenarios
1718
*
1819
* It's an IPC using one CPU word with the encoding:
1920
*
@@ -24,15 +25,17 @@
2425
struct rt_completion
2526
{
2627
/* suspended thread, and completed flag */
27-
rt_base_t susp_thread_n_flag;
28+
rt_atomic_t susp_thread_n_flag;
2829
};
2930

3031
#define RT_COMPLETION_INIT(comp) {0}
3132

3233
void rt_completion_init(struct rt_completion *completion);
3334
rt_err_t rt_completion_wait(struct rt_completion *completion,
3435
rt_int32_t timeout);
36+
rt_err_t rt_completion_wait_flags(struct rt_completion *completion,
37+
rt_int32_t timeout, int suspend_flag);
3538
void rt_completion_done(struct rt_completion *completion);
3639
rt_err_t rt_completion_wakeup(struct rt_completion *completion);
37-
40+
rt_err_t rt_completion_wakeup_by_errno(struct rt_completion *completion, rt_err_t error);
3841
#endif

components/drivers/ipc/Kconfig

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
menuconfig RT_USING_DEVICE_IPC
2+
bool "Using device drivers IPC"
3+
default y
4+
5+
if RT_USING_DEVICE_IPC
6+
config RT_UNAMED_PIPE_NUMBER
7+
int "The number of unamed pipe"
8+
default 64
9+
10+
config RT_USING_SYSTEM_WORKQUEUE
11+
bool "Using system default workqueue"
12+
default n
13+
14+
if RT_USING_SYSTEM_WORKQUEUE
15+
config RT_SYSTEM_WORKQUEUE_STACKSIZE
16+
int "The stack size for system workqueue thread"
17+
default 2048
18+
19+
config RT_SYSTEM_WORKQUEUE_PRIORITY
20+
int "The priority level of system workqueue thread"
21+
default 23
22+
endif
23+
endif

components/drivers/ipc/SConscript

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ if not GetDepend('RT_USING_HEAP'):
88
SrcRemove(src, 'dataqueue.c')
99
SrcRemove(src, 'pipe.c')
1010

11+
if not GetDepend('RT_USING_SMP'):
12+
SrcRemove(src, 'completion_mp.c')
13+
else:
14+
SrcRemove(src, 'completion_up.c')
15+
1116
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_DEVICE_IPC'], CPPPATH = CPPPATH, LOCAL_CPPDEFINES=['__RT_IPC_SOURCE__'])
1217

1318
Return('group')
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2006-2024, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-04-26 Shell lockless rt_completion
9+
*/
10+
#include <rtthread.h>
11+
#include <rthw.h>
12+
#include <rtdevice.h>
13+
14+
/**
15+
* @brief This function indicates a completion has done.
16+
*
17+
* @param completion is a pointer to a completion object.
18+
*/
19+
void rt_completion_done(struct rt_completion *completion)
20+
{
21+
rt_completion_wakeup_by_errno(completion, -1);
22+
}
23+
RTM_EXPORT(rt_completion_done);
24+
25+
/**
26+
* @brief This function indicates a completion has done and wakeup the thread
27+
*
28+
* @param completion is a pointer to a completion object.
29+
* @return RT_EOK if wakeup succeed.
30+
* RT_EEMPTY if wakeup failure and the completion is set to completed.
31+
* RT_EBUSY if the completion is still in completed state
32+
*/
33+
rt_err_t rt_completion_wakeup(struct rt_completion *completion)
34+
{
35+
return rt_completion_wakeup_by_errno(completion, -1);
36+
}
37+
38+
/**
39+
* @brief This function will wait for a completion, if the completion is unavailable, the thread shall wait for
40+
* the completion up to a specified time.
41+
*
42+
* @param completion is a pointer to a completion object.
43+
*
44+
* @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for
45+
* the completion done up to the amount of time specified by the argument.
46+
* NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the
47+
* completion is unavailable, the thread will be waitting forever.
48+
*
49+
* @return Return the operation status. ONLY when the return value is RT_EOK, the operation is successful.
50+
* If the return value is any other values, it means that the completion wait failed.
51+
*
52+
* @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context.
53+
*/
54+
rt_err_t rt_completion_wait(struct rt_completion *completion,
55+
rt_int32_t timeout)
56+
{
57+
return rt_completion_wait_flags(completion, timeout, RT_UNINTERRUPTIBLE);
58+
}
59+
RTM_EXPORT(rt_completion_wait);

0 commit comments

Comments
 (0)