Convert code to use u{8,16,32,64}_t and s{8,16,32,64}_t instead of C99 integer types. This handles the remaining includes and kernel, plus touching up various points that we skipped because of include dependancies. We also convert the PRI printf formatters in the arch code over to normal formatters. Jira: ZEP-2051 Change-Id: Iecbb12601a3ee4ea936fd7ddea37788a645b08b0 Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
185 lines
3.8 KiB
C
185 lines
3.8 KiB
C
/*
|
|
* Copyright (c) 2010-2016 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* @brief dynamic-size QUEUE object.
|
|
*/
|
|
|
|
|
|
#include <kernel.h>
|
|
#include <kernel_structs.h>
|
|
#include <debug/object_tracing_common.h>
|
|
#include <toolchain.h>
|
|
#include <sections.h>
|
|
#include <wait_q.h>
|
|
#include <ksched.h>
|
|
#include <misc/slist.h>
|
|
#include <init.h>
|
|
|
|
extern struct k_queue _k_queue_list_start[];
|
|
extern struct k_queue _k_queue_list_end[];
|
|
|
|
struct k_queue *_trace_list_k_queue;
|
|
|
|
#ifdef CONFIG_OBJECT_TRACING
|
|
|
|
/*
|
|
* Complete initialization of statically defined queues.
|
|
*/
|
|
static int init_queue_module(struct device *dev)
|
|
{
|
|
ARG_UNUSED(dev);
|
|
|
|
struct k_queue *queue;
|
|
|
|
for (queue = _k_queue_list_start; queue < _k_queue_list_end; queue++) {
|
|
SYS_TRACING_OBJ_INIT(k_queue, queue);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
SYS_INIT(init_queue_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
|
|
|
|
#endif /* CONFIG_OBJECT_TRACING */
|
|
|
|
void k_queue_init(struct k_queue *queue)
|
|
{
|
|
sys_slist_init(&queue->data_q);
|
|
sys_dlist_init(&queue->wait_q);
|
|
|
|
_INIT_OBJ_POLL_EVENT(queue);
|
|
|
|
SYS_TRACING_OBJ_INIT(k_queue, queue);
|
|
}
|
|
|
|
static void prepare_thread_to_run(struct k_thread *thread, void *data)
|
|
{
|
|
_abort_thread_timeout(thread);
|
|
_ready_thread(thread);
|
|
_set_thread_return_value_with_data(thread, 0, data);
|
|
}
|
|
|
|
/* returns 1 if a reschedule must take place, 0 otherwise */
|
|
static inline int handle_poll_event(struct k_queue *queue)
|
|
{
|
|
#ifdef CONFIG_POLL
|
|
u32_t state = K_POLL_STATE_DATA_AVAILABLE;
|
|
|
|
return queue->poll_event ?
|
|
_handle_obj_poll_event(&queue->poll_event, state) : 0;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
void k_queue_insert(struct k_queue *queue, void *prev, void *data)
|
|
{
|
|
struct k_thread *first_pending_thread;
|
|
unsigned int key;
|
|
|
|
key = irq_lock();
|
|
|
|
first_pending_thread = _unpend_first_thread(&queue->wait_q);
|
|
|
|
if (first_pending_thread) {
|
|
prepare_thread_to_run(first_pending_thread, data);
|
|
if (!_is_in_isr() && _must_switch_threads()) {
|
|
(void)_Swap(key);
|
|
return;
|
|
}
|
|
} else {
|
|
sys_slist_insert(&queue->data_q, prev, data);
|
|
if (handle_poll_event(queue)) {
|
|
(void)_Swap(key);
|
|
return;
|
|
}
|
|
}
|
|
|
|
irq_unlock(key);
|
|
}
|
|
|
|
void k_queue_append(struct k_queue *queue, void *data)
|
|
{
|
|
return k_queue_insert(queue, queue->data_q.tail, data);
|
|
}
|
|
|
|
void k_queue_prepend(struct k_queue *queue, void *data)
|
|
{
|
|
return k_queue_insert(queue, NULL, data);
|
|
}
|
|
|
|
void k_queue_append_list(struct k_queue *queue, void *head, void *tail)
|
|
{
|
|
__ASSERT(head && tail, "invalid head or tail");
|
|
|
|
struct k_thread *first_thread, *thread;
|
|
unsigned int key;
|
|
|
|
key = irq_lock();
|
|
|
|
first_thread = _peek_first_pending_thread(&queue->wait_q);
|
|
while (head && ((thread = _unpend_first_thread(&queue->wait_q)))) {
|
|
prepare_thread_to_run(thread, head);
|
|
head = *(void **)head;
|
|
}
|
|
|
|
if (head) {
|
|
sys_slist_append_list(&queue->data_q, head, tail);
|
|
}
|
|
|
|
if (first_thread) {
|
|
if (!_is_in_isr() && _must_switch_threads()) {
|
|
(void)_Swap(key);
|
|
return;
|
|
}
|
|
} else {
|
|
if (handle_poll_event(queue)) {
|
|
(void)_Swap(key);
|
|
return;
|
|
}
|
|
}
|
|
|
|
irq_unlock(key);
|
|
}
|
|
|
|
void k_queue_merge_slist(struct k_queue *queue, sys_slist_t *list)
|
|
{
|
|
__ASSERT(!sys_slist_is_empty(list), "list must not be empty");
|
|
|
|
/*
|
|
* note: this works as long as:
|
|
* - the slist implementation keeps the next pointer as the first
|
|
* field of the node object type
|
|
* - list->tail->next = NULL.
|
|
*/
|
|
k_queue_append_list(queue, list->head, list->tail);
|
|
sys_slist_init(list);
|
|
}
|
|
|
|
void *k_queue_get(struct k_queue *queue, s32_t timeout)
|
|
{
|
|
unsigned int key;
|
|
void *data;
|
|
|
|
key = irq_lock();
|
|
|
|
if (likely(!sys_slist_is_empty(&queue->data_q))) {
|
|
data = sys_slist_get_not_empty(&queue->data_q);
|
|
irq_unlock(key);
|
|
return data;
|
|
}
|
|
|
|
if (timeout == K_NO_WAIT) {
|
|
irq_unlock(key);
|
|
return NULL;
|
|
}
|
|
|
|
_pend_current_thread(&queue->wait_q, timeout);
|
|
|
|
return _Swap(key) ? NULL : _current->base.swap_data;
|
|
}
|