Skip to content

Commit 9f40c5d

Browse files
kernel: sys_workq: add k_is_in_sys_work API
Add k_is_in_sys_work() API which returns true if the thread context is the system workqueue thread and the thread is currently servicing a work item. Useful for checking if blocking is safe or required in the case of calling an API which uses the system work queue internally. Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent bb1e9f9 commit 9f40c5d

File tree

8 files changed

+25
-9
lines changed

8 files changed

+25
-9
lines changed

include/zephyr/kernel.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,19 @@ void k_thread_time_slice_set(struct k_thread *th, int32_t slice_ticks,
11811181
*/
11821182
bool k_is_in_isr(void);
11831183

1184+
/**
1185+
* @brief Determine if code is running from system work item
1186+
*
1187+
* This routine allows the caller to customize its actions, depending on
1188+
* whether it is running fom a system work item.
1189+
*
1190+
* @funcprops \isr_ok
1191+
*
1192+
* @return false if noit invoked from a system work item.
1193+
* @return true if invoked from a system work item.
1194+
*/
1195+
bool k_is_in_sys_work(void);
1196+
11841197
/**
11851198
* @brief Determine if code is running in a preemptible thread.
11861199
*

kernel/work.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,3 +1175,9 @@ bool k_work_flush_delayable(struct k_work_delayable *dwork,
11751175
}
11761176

11771177
#endif /* CONFIG_SYS_CLOCK_EXISTS */
1178+
1179+
bool k_is_in_sys_work(void)
1180+
{
1181+
return k_current_get() == k_work_queue_thread_get(&k_sys_work_q) &&
1182+
flag_test(&k_sys_work_q.flags, K_WORK_QUEUE_BUSY_BIT);
1183+
}

subsys/bluetooth/host/att.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t
732732
default: {
733733
k_tid_t current_thread = k_current_get();
734734

735-
if (current_thread == k_work_queue_thread_get(&k_sys_work_q)) {
735+
if (k_is_in_sys_work()) {
736736
/* No blocking in the sysqueue. */
737737
timeout = K_NO_WAIT;
738738
} else if (current_thread == att_handle_rsp_thread) {

subsys/bluetooth/host/classic/hfp_ag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ static struct bt_ag_tx *bt_ag_tx_alloc(void)
215215
* so if we're in the same workqueue but there are no immediate
216216
* contexts available, there's no chance we'll get one by waiting.
217217
*/
218-
if (k_current_get() == &k_sys_work_q.thread) {
218+
if (k_is_in_sys_work()) {
219219
return k_fifo_get(&ag_tx_free, K_NO_WAIT);
220220
}
221221

subsys/bluetooth/host/conn.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,8 +1606,7 @@ struct net_buf *bt_conn_create_pdu_timeout(struct net_buf_pool *pool,
16061606
*/
16071607
__ASSERT_NO_MSG(!k_is_in_isr());
16081608

1609-
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) &&
1610-
k_current_get() == k_work_queue_thread_get(&k_sys_work_q)) {
1609+
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) && k_is_in_sys_work()) {
16111610
LOG_WRN("Timeout discarded. No blocking in syswq.");
16121611
timeout = K_NO_WAIT;
16131612
}

subsys/bluetooth/host/hci_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf,
410410
/* Since the commands are now processed in the syswq, we cannot suspend
411411
* and wait. We have to send the command from the current context.
412412
*/
413-
if (k_current_get() == &k_sys_work_q.thread) {
413+
if (k_is_in_sys_work()) {
414414
/* drain the command queue until we get to send the command of interest. */
415415
struct net_buf *cmd = NULL;
416416

subsys/bluetooth/host/l2cap.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,7 @@ struct net_buf *bt_l2cap_create_pdu_timeout(struct net_buf_pool *pool,
674674
size_t reserve,
675675
k_timeout_t timeout)
676676
{
677-
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) &&
678-
k_current_get() == k_work_queue_thread_get(&k_sys_work_q)) {
677+
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) && k_is_in_sys_work()) {
679678
timeout = K_NO_WAIT;
680679
}
681680

subsys/input/input.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ int input_report(const struct device *dev,
5252
#ifdef CONFIG_INPUT_MODE_THREAD
5353
int ret;
5454

55-
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) &&
56-
k_current_get() == k_work_queue_thread_get(&k_sys_work_q)) {
55+
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) && k_is_in_sys_work()) {
5756
LOG_DBG("Timeout discarded. No blocking in syswq.");
5857
timeout = K_NO_WAIT;
5958
}

0 commit comments

Comments
 (0)