TNeoKernel  v1.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
tn_dqueue.h
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * TNeoKernel: real-time kernel initially based on TNKernel
4  *
5  * TNKernel: copyright © 2004, 2013 Yuri Tiomkin.
6  * PIC32-specific routines: copyright © 2013, 2014 Anders Montonen.
7  * TNeoKernel: copyright © 2014 Dmitry Frank.
8  *
9  * TNeoKernel was born as a thorough review and re-implementation of
10  * TNKernel. The new kernel has well-formed code, inherited bugs are fixed
11  * as well as new features being added, and it is tested carefully with
12  * unit-tests.
13  *
14  * API is changed somewhat, so it's not 100% compatible with TNKernel,
15  * hence the new name: TNeoKernel.
16  *
17  * Permission to use, copy, modify, and distribute this software in source
18  * and binary forms and its documentation for any purpose and without fee
19  * is hereby granted, provided that the above copyright notice appear
20  * in all copies and that both that copyright notice and this permission
21  * notice appear in supporting documentation.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE DMITRY FRANK AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DMITRY FRANK OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33  * THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  ******************************************************************************/
36 
37 /**
38  * \file
39  *
40  * A data queue is a FIFO that stores pointer (of type `void *`) in each cell,
41  * called (in uITRON style) a data element. A data queue also has an associated
42  * wait queue each for sending (`wait_send` queue) and for receiving
43  * (`wait_receive` queue). A task that sends a data element tries to put the
44  * data element into the FIFO. If there is no space left in the FIFO, the task
45  * is switched to the waiting state and placed in the data queue's `wait_send`
46  * queue until space appears (another task gets a data element from the data
47  * queue). A task that receives a data element tries to get a data element
48  * from the FIFO. If the FIFO is empty (there is no data in the data queue),
49  * the task is switched to the waiting state and placed in the data queue's
50  * `wait_receive` queue until data element arrive (another task puts some data
51  * element into the data queue). To use a data queue just for the synchronous
52  * message passing, set size of the FIFO to 0. The data element to be sent and
53  * received can be interpreted as a pointer or an integer and may have value 0
54  * (`NULL`).
55  *
56  */
57 
58 #ifndef _TN_DQUEUE_H
59 #define _TN_DQUEUE_H
60 
61 /*******************************************************************************
62  * INCLUDED FILES
63  ******************************************************************************/
64 
65 #include "tn_list.h"
66 #include "tn_common.h"
67 
68 
69 
70 
71 
72 #ifdef __cplusplus
73 extern "C" { /*}*/
74 #endif
75 
76 /*******************************************************************************
77  * PUBLIC TYPES
78  ******************************************************************************/
79 
80 /**
81  * Structure representing data queue object
82  */
83 struct TN_DQueue {
84  ///
85  /// list of tasks waiting to send data
86  struct TN_ListItem wait_send_list;
87  ///
88  /// list of tasks waiting to receive data
89  struct TN_ListItem wait_receive_list;
90 
91  ///
92  /// array of `void *` to store data queue items. Can be `NULL`.
93  void **data_fifo;
94  ///
95  /// capacity (total items count). Can be 0.
96  int items_cnt;
97  ///
98  /// count of non-free items in `data_fifo`
100  ///
101  /// index of the item which will be written next time
102  int head_idx;
103  ///
104  /// index of the item which will be read next time
105  int tail_idx;
106  ///
107  /// id for object validity verification
109 };
110 
111 /**
112  * DQueue-specific fields related to waiting task,
113  * to be included in struct TN_Task.
114  */
116  /// if task tries to send the data to the data queue,
117  /// and there's no space in the queue, value to put to queue is stored
118  /// in this field
119  void *data_elem;
120 };
121 
122 
123 /*******************************************************************************
124  * GLOBAL VARIABLES
125  ******************************************************************************/
126 
127 /*******************************************************************************
128  * DEFINITIONS
129  ******************************************************************************/
130 
131 /*******************************************************************************
132  * PUBLIC FUNCTION PROTOTYPES
133  ******************************************************************************/
134 
135 /**
136  * Construct data queue. `id_dque` member should not contain `#TN_ID_DATAQUEUE`,
137  * otherwise, `#TN_RC_WPARAM` is returned.
138  *
139  * $(TN_CALL_FROM_TASK)
140  * $(TN_CALL_FROM_ISR)
141  * $(TN_LEGEND_LINK)
142  *
143  * @param dque pointer to already allocated struct TN_DQueue.
144  * @param data_fifo pointer to already allocated array of `void *` to store
145  * data queue items. Can be NULL.
146  * @param items_cnt capacity of queue
147  * (count of elements in the `data_fifo` array)
148  * Can be 0.
149  *
150  * @return
151  * * `#TN_RC_OK` if queue was successfully created;
152  * * If `#TN_CHECK_PARAM` is non-zero, additional return code
153  * is available: `#TN_RC_WPARAM`.
154  */
156  struct TN_DQueue *dque,
157  void **data_fifo,
158  int items_cnt
159  );
160 
161 
162 /**
163  * Destruct data queue.
164  *
165  * All tasks that wait for writing to or reading from the queue become
166  * runnable with `#TN_RC_DELETED` code returned. TN_RCode, struct TN_Task.
167  *
168  * $(TN_CALL_FROM_TASK)
169  * $(TN_CAN_SWITCH_CONTEXT)
170  * $(TN_LEGEND_LINK)
171  *
172  * @param dque pointer to data queue to be deleted
173  *
174  * @return
175  * * `#TN_RC_OK` if queue was successfully deleted;
176  * * `#TN_RC_WCONTEXT` if called from wrong context;
177  * * If `#TN_CHECK_PARAM` is non-zero, additional return codes
178  * are available: `#TN_RC_WPARAM` and `#TN_RC_INVALID_OBJ`.
179  */
180 enum TN_RCode tn_queue_delete(struct TN_DQueue *dque);
181 
182 
183 /**
184  * Send the data element specified by the `p_data` to the data queue
185  * specified by the `dque`.
186  *
187  * If there are tasks in the data queue's `wait_receive` list already, the
188  * function releases the task from the head of the `wait_receive` list, makes
189  * this task runnable and transfers the parameter `p_data` to task's
190  * function, that caused it to wait.
191  *
192  * If there are no tasks in the data queue's `wait_receive` list, parameter
193  * `p_data` is placed to the tail of data FIFO. If the data FIFO is full,
194  * behavior depends on the `timeout` value: refer to `#TN_Timeout`.
195  *
196  * $(TN_CALL_FROM_TASK)
197  * $(TN_CAN_SWITCH_CONTEXT)
198  * $(TN_CAN_SLEEP)
199  * $(TN_LEGEND_LINK)
200  *
201  * @param dque pointer to data queue to send data to
202  * @param p_data value to send
203  * @param timeout refer to `#TN_Timeout`
204  *
205  * @return
206  * * `#TN_RC_OK` if data was successfully sent;
207  * * `#TN_RC_WCONTEXT` if called from wrong context;
208  * * Other possible return codes depend on `timeout` value,
209  * refer to `#TN_Timeout`
210  * * If `#TN_CHECK_PARAM` is non-zero, additional return codes
211  * are available: `#TN_RC_WPARAM` and `#TN_RC_INVALID_OBJ`.
212  *
213  * @see `#TN_Timeout`
214  */
216  struct TN_DQueue *dque,
217  void *p_data,
218  TN_Timeout timeout
219  );
220 
221 /**
222  * The same as `tn_queue_send()` with zero timeout
223  *
224  * $(TN_CALL_FROM_TASK)
225  * $(TN_CAN_SWITCH_CONTEXT)
226  * $(TN_LEGEND_LINK)
227  */
229  struct TN_DQueue *dque,
230  void *p_data
231  );
232 
233 /**
234  * The same as `tn_queue_send()` with zero timeout, but for using in the ISR.
235  *
236  * $(TN_CALL_FROM_ISR)
237  * $(TN_CAN_SWITCH_CONTEXT)
238  * $(TN_LEGEND_LINK)
239  */
241  struct TN_DQueue *dque,
242  void *p_data
243  );
244 
245 /**
246  * Receive the data element from the data queue specified by the `dque` and
247  * place it into the address specified by the `pp_data`. If the FIFO already
248  * has data, function removes an entry from the end of the data queue FIFO and
249  * returns it into the `pp_data` function parameter.
250  *
251  * If there are task(s) in the data queue's `wait_send` list, first one gets
252  * removed from the head of `wait_send` list, becomes runnable and puts the
253  * data entry, stored in this task, to the tail of data FIFO. If there are no
254  * entries in the data FIFO and there are no tasks in the wait_send list,
255  * behavior depends on the `timeout` value: refer to `#TN_Timeout`.
256  *
257  * $(TN_CALL_FROM_TASK)
258  * $(TN_CAN_SWITCH_CONTEXT)
259  * $(TN_CAN_SLEEP)
260  * $(TN_LEGEND_LINK)
261  *
262  * @param dque pointer to data queue to receive data from
263  * @param pp_data pointer to location to store the value
264  * @param timeout refer to `#TN_Timeout`
265  *
266  * @return
267  * * `#TN_RC_OK` if data was successfully received;
268  * * `#TN_RC_WCONTEXT` if called from wrong context;
269  * * Other possible return codes depend on `timeout` value,
270  * refer to `#TN_Timeout`
271  * * If `#TN_CHECK_PARAM` is non-zero, additional return codes
272  * are available: `#TN_RC_WPARAM` and `#TN_RC_INVALID_OBJ`.
273  *
274  * @see `#TN_Timeout`
275  */
277  struct TN_DQueue *dque,
278  void **pp_data,
279  TN_Timeout timeout
280  );
281 
282 /**
283  * The same as `tn_queue_receive()` with zero timeout
284  *
285  * $(TN_CALL_FROM_TASK)
286  * $(TN_CAN_SWITCH_CONTEXT)
287  * $(TN_LEGEND_LINK)
288  */
290  struct TN_DQueue *dque,
291  void **pp_data
292  );
293 
294 /**
295  * The same as `tn_queue_receive()` with zero timeout, but for using in the ISR.
296  *
297  * $(TN_CALL_FROM_ISR)
298  * $(TN_CAN_SWITCH_CONTEXT)
299  * $(TN_LEGEND_LINK)
300  */
302  struct TN_DQueue *dque,
303  void **pp_data
304  );
305 
306 
307 
308 
309 #ifdef __cplusplus
310 } /* extern "C" */
311 #endif
312 
313 #endif // _TN_DQUEUE_H
314 
315 /*******************************************************************************
316  * end of file
317  ******************************************************************************/
318 
319 
enum TN_RCode tn_queue_receive_polling(struct TN_DQueue *dque, void **pp_data)
The same as tn_queue_receive() with zero timeout.
struct TN_ListItem wait_receive_list
list of tasks waiting to receive data
Definition: tn_dqueue.h:89
struct TN_ListItem wait_send_list
list of tasks waiting to send data
Definition: tn_dqueue.h:86
enum TN_ObjId id_dque
id for object validity verification
Definition: tn_dqueue.h:108
enum TN_RCode tn_queue_ireceive_polling(struct TN_DQueue *dque, void **pp_data)
The same as tn_queue_receive() with zero timeout, but for using in the ISR.
Structure representing data queue object.
Definition: tn_dqueue.h:83
TN_RCode
Result code returned by kernel services.
Definition: tn_common.h:99
enum TN_RCode tn_queue_send(struct TN_DQueue *dque, void *p_data, TN_Timeout timeout)
Send the data element specified by the p_data to the data queue specified by the dque.
void ** data_fifo
array of void * to store data queue items. Can be NULL.
Definition: tn_dqueue.h:93
DQueue-specific fields related to waiting task, to be included in struct TN_Task. ...
Definition: tn_dqueue.h:115
TN_ObjId
Magic number for object validity verification.
Definition: tn_common.h:87
unsigned long TN_Timeout
The value representing maximum number of system ticks to wait.
Definition: tn_common.h:203
Definitions used through the whole kernel.
int head_idx
index of the item which will be written next time
Definition: tn_dqueue.h:102
int filled_items_cnt
count of non-free items in data_fifo
Definition: tn_dqueue.h:99
int items_cnt
capacity (total items count). Can be 0.
Definition: tn_dqueue.h:96
void * data_elem
if task tries to send the data to the data queue, and there's no space in the queue, value to put to queue is stored in this field
Definition: tn_dqueue.h:119
int tail_idx
index of the item which will be read next time
Definition: tn_dqueue.h:105
enum TN_RCode tn_queue_create(struct TN_DQueue *dque, void **data_fifo, int items_cnt)
Construct data queue.
enum TN_RCode tn_queue_receive(struct TN_DQueue *dque, void **pp_data, TN_Timeout timeout)
Receive the data element from the data queue specified by the dque and place it into the address spec...
enum TN_RCode tn_queue_send_polling(struct TN_DQueue *dque, void *p_data)
The same as tn_queue_send() with zero timeout.
enum TN_RCode tn_queue_isend_polling(struct TN_DQueue *dque, void *p_data)
The same as tn_queue_send() with zero timeout, but for using in the ISR.
enum TN_RCode tn_queue_delete(struct TN_DQueue *dque)
Destruct data queue.