1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef __THREAD_H__
8 #define __THREAD_H__
9 
10 #include "freertos/FreeRTOSConfig.h"
11 #include "freertos/FreeRTOS.h"
12 #include "freertos/queue.h"
13 #include "freertos/task.h"
14 #include "osi/semaphore.h"
15 #include "esp_task.h"
16 #include "bt_common.h"
17 
18 #define portBASE_TYPE int
19 
20 #define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
21 
22 struct osi_thread;
23 struct osi_event;
24 
25 typedef struct osi_thread osi_thread_t;
26 
27 typedef void (*osi_thread_func_t)(void *context);
28 
29 typedef enum {
30     OSI_THREAD_CORE_0 = 0,
31     OSI_THREAD_CORE_1,
32     OSI_THREAD_CORE_AFFINITY,
33 } osi_thread_core_t;
34 
35 /*
36  * brief: Create a thread or task
37  * param name: thread name
38  * param stack_size: thread stack size
39  * param priority: thread priority
40  * param core: the CPU core which this thread run, OSI_THREAD_CORE_AFFINITY means unspecific CPU core
41  * param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index
42  * return : if create successfully, return thread handler; otherwise return NULL.
43  */
44 osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]);
45 
46 /*
47  * brief: Destroy a thread or task
48  * param thread: point of thread handler
49  */
50 void osi_thread_free(osi_thread_t *thread);
51 
52 /*
53  * brief: Post an msg to a thread and told the thread call the function
54  * param thread: point of thread handler
55  * param func: callback function that called by target thread
56  * param context: argument of callback function
57  * param queue_idx: the queue which the msg send to
58  * param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
59  * return : if post successfully, return true, otherwise return false
60  */
61 bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout);
62 
63 /*
64  * brief: Set the priority of thread
65  * param thread: point of thread handler
66  * param priority: priority
67  * return : if set successfully, return true, otherwise return false
68  */
69 bool osi_thread_set_priority(osi_thread_t *thread, int priority);
70 
71 /* brief: Get thread name
72  * param thread: point of thread handler
73  * return: constant point of thread name
74  */
75 const char *osi_thread_name(osi_thread_t *thread);
76 
77 /* brief: Get the size of the specified queue
78  * param thread: point of thread handler
79  * param wq_idx: the queue index of the thread
80  * return: queue size
81  */
82 int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
83 
84 /*
85  * brief: Create an osi_event struct and register the handler function and its argument
86  *        An osi_event is a kind of work that can be posted to the workqueue of osi_thread to process,
87  *        but the work can have at most one instance the thread workqueue before it is processed. This
88  *        allows the "single post, multiple data processing" jobs.
89  * param func: the handler to process the job
90  * param context: the argument to be passed to the handler function when the job is being processed
91  * return: NULL if no memory, otherwise a valid struct pointer
92  */
93 struct osi_event *osi_event_create(osi_thread_func_t func, void *context);
94 
95 /*
96  * brief: Bind an osi_event to a specific work queue for an osi_thread.
97  *        After binding is completed, a function call of API osi_thread_post_event will send a work
98  *        to the workqueue of the thread, with specified queue index.
99  * param func: event: the pointer to osi_event that is created using osi_event_create
100  * param thread: the pointer to osi_thread that is created using osi_thread_create
101  * param queue_idx: the index of the workqueue of the specified osi_thread, with range starting from 0 to work_queue_num - 1
102  * return: true if osi_event binds to the thread's workqueue successfully, otherwise false
103  */
104 bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx);
105 
106 /*
107  * brief: Destroy the osi_event struct created by osi_event_create and free the allocated memory
108  * param event: the pointer to osi_event
109  */
110 void osi_event_delete(struct osi_event* event);
111 
112 /*
113  * brief: try sending a work to the binded thread's workqueue, so that it can be handled by the worker thread
114  * param event: pointer to osi_event, created by osi_event_create
115  * param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
116  * return: true if the message is enqueued to the thread workqueue, otherwise failed
117  * note: if the return value of function is false, it is the case that the workqueue of the thread is full, and users
118  *       are expected to post the event sometime later to get the work handled.
119  */
120 bool osi_thread_post_event(struct osi_event *event, uint32_t timeout);
121 
122 #endif /* __THREAD_H__ */
123