zephyr/kernel/nanokernel/nano_timer.c
Juan Manuel Cruz caa17577ef debug: kernel's object tracing api
Restructure the kernel's object tracing implementation
to provide a public API that allows debug tools to use
the debug hooks easier and allows kernel developers
to extend the kernel's object tracing scope and include
new kernel objects easier.

The API provides the trace list abstraction to keep track
of different types of kernel objects. The API contains
a simple single-linked list implementation that allows
to save space and simplifies the access to the data for
debug tools such as gdb.

Change-Id: Ic4d393d584576f67f2c5b706e61bae08869debba
Signed-off-by: Juan Manuel Cruz <juan.m.cruz.alcaraz@intel.com>
2016-03-11 12:00:07 +00:00

160 lines
3.6 KiB
C

/* nano_timer.c - timer for nanokernel-only systems */
/*
* Copyright (c) 1997-2014 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <nano_private.h>
#include <misc/debug/object_tracing_common.h>
struct nano_timer *_nano_timer_list;
void nano_timer_init(struct nano_timer *timer, void *data)
{
nano_lifo_init(&timer->lifo);
timer->userData = data;
SYS_TRACING_OBJ_INIT(nano_timer, timer);
}
FUNC_ALIAS(_timer_start, nano_isr_timer_start, void);
FUNC_ALIAS(_timer_start, nano_fiber_timer_start, void);
FUNC_ALIAS(_timer_start, nano_task_timer_start, void);
FUNC_ALIAS(_timer_start, nano_timer_start, void);
/**
*
* @brief Start a nanokernel timer (generic implementation)
*
* This function starts a previously initialized nanokernel timer object.
* The timer will expire in <ticks> system clock ticks.
*
* @param timer The Timer to start
* @param ticks The number of system ticks before expiration
*
* @return N/A
*/
void _timer_start(struct nano_timer *timer, int ticks)
{
unsigned int imask;
struct nano_timer *cur;
struct nano_timer *prev = NULL;
timer->ticks = ticks;
imask = irq_lock();
cur = _nano_timer_list;
while (cur && (timer->ticks > cur->ticks)) {
timer->ticks -= cur->ticks;
prev = cur;
cur = cur->link;
}
timer->link = cur;
if (cur != NULL)
cur->ticks -= timer->ticks;
if (prev != NULL)
prev->link = timer;
else
_nano_timer_list = timer;
irq_unlock(imask);
}
/**
* @brief Stop a nanokernel timer (generic implementation)
*
* This function stops a previously started nanokernel timer object.
* @param timer Timer to stop
* @return N/A
*/
static void _timer_stop(struct nano_timer *timer)
{
unsigned int imask;
struct nano_timer *cur;
struct nano_timer *prev = NULL;
imask = irq_lock();
cur = _nano_timer_list;
/* find prev */
while (cur && cur != timer) {
prev = cur;
cur = cur->link;
}
/* if found it, remove it */
if (cur) {
/* if it was first */
if (prev == NULL) {
_nano_timer_list = timer->link;
/* if not last */
if (_nano_timer_list)
_nano_timer_list->ticks += timer->ticks;
} else {
prev->link = timer->link;
/* if not last */
if (prev->link)
prev->link->ticks += timer->ticks;
}
}
/* now the timer can't expire since it is removed from the list */
irq_unlock(imask);
}
FUNC_ALIAS(_timer_stop_non_preemptible, nano_isr_timer_stop, void);
FUNC_ALIAS(_timer_stop_non_preemptible, nano_fiber_timer_stop, void);
void _timer_stop_non_preemptible(struct nano_timer *timer)
{
extern void _lifo_put_non_preemptible(struct nano_lifo *lifo, void *data);
_timer_stop(timer);
/* if there was a waiter, kick it */
if (timer->lifo.wait_q.head) {
_lifo_put_non_preemptible(&timer->lifo, (void *)0);
}
}
void nano_task_timer_stop(struct nano_timer *timer)
{
_timer_stop(timer);
/* if there was a waiter, kick it */
if (timer->lifo.wait_q.head) {
nano_task_lifo_put(&timer->lifo, (void *)0);
}
}
void nano_timer_stop(struct nano_timer *timer)
{
static void (*func[3])(struct nano_timer *) = {
nano_isr_timer_stop,
nano_fiber_timer_stop,
nano_task_timer_stop,
};
func[sys_execution_context_type_get()](timer);
}