mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
Change task messages to events
Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:7461 TEST=manual make BOARD={bds,link,daisy} make tests flash link system and make sure it boots Change-Id: I1241a1895c083e387e38ddab01ac346ca4474eb9
This commit is contained in:
@@ -35,17 +35,17 @@ static struct mutex port_mutex[NUM_PORTS];
|
||||
static int wait_idle(int port)
|
||||
{
|
||||
int i;
|
||||
int wait_msg;
|
||||
int event;
|
||||
|
||||
i = LM4_I2C_MCS(port);
|
||||
while (i & 0x01) {
|
||||
/* Port is busy, so wait for the interrupt */
|
||||
task_waiting_on_port[port] = task_get_current();
|
||||
LM4_I2C_MIMR(port) = 0x03;
|
||||
wait_msg = task_wait_msg(1000000);
|
||||
event = task_wait_event(1000000);
|
||||
LM4_I2C_MIMR(port) = 0x00;
|
||||
task_waiting_on_port[port] = TASK_ID_INVALID;
|
||||
if (wait_msg == 1 << TASK_ID_TIMER)
|
||||
if (event == TASK_EVENT_TIMER)
|
||||
return EC_ERROR_TIMEOUT;
|
||||
|
||||
i = LM4_I2C_MCS(port);
|
||||
@@ -271,9 +271,9 @@ static void handle_interrupt(int port)
|
||||
LM4_I2C_MICR(port) = LM4_I2C_MMIS(port);
|
||||
|
||||
/* Wake up the task which was waiting on the interrupt, if any */
|
||||
/* TODO: send message based on I2C port number? */
|
||||
/* TODO: set event based on I2C port number? */
|
||||
if (id != TASK_ID_INVALID)
|
||||
task_send_msg(id, id, 0);
|
||||
task_wake(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ void keyboard_scan_task(void)
|
||||
|
||||
while (1) {
|
||||
wait_for_interrupt();
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
|
||||
enter_polling_mode();
|
||||
/* Busy polling keyboard state. */
|
||||
@@ -412,9 +412,8 @@ static void matrix_interrupt(void)
|
||||
{
|
||||
uint32_t ris = clear_matrix_interrupt_status();
|
||||
|
||||
if (ris) {
|
||||
task_send_msg(TASK_ID_KEYSCAN, TASK_ID_KEYSCAN, 0);
|
||||
}
|
||||
if (ris)
|
||||
task_wake(TASK_ID_KEYSCAN);
|
||||
}
|
||||
DECLARE_IRQ(KB_SCAN_ROW_IRQ, matrix_interrupt, 3);
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ static void lpc_interrupt(void)
|
||||
}
|
||||
if (mis & LM4_LPC_INT_MASK(LPC_CH_KEYBOARD, 1)) {
|
||||
/* Host picks up the data, try to send remaining bytes */
|
||||
task_send_msg(TASK_ID_I8042CMD, TASK_ID_I8042CMD, 0);
|
||||
task_wake(TASK_ID_I8042CMD);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ void power_button_interrupt(enum gpio_signal signal)
|
||||
* remainder of the interval. The alternative would be to have the
|
||||
* task wake up _every_ debounce_us on its own; that's less desirable
|
||||
* when the EC should be sleeping. */
|
||||
task_send_msg(TASK_ID_POWERBTN, TASK_ID_POWERBTN, 0);
|
||||
task_wake(TASK_ID_POWERBTN);
|
||||
}
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ void power_button_task(void)
|
||||
* early.) */
|
||||
uart_printf("[%T PB task %d wait %d]\n",
|
||||
pwrbtn_state, d);
|
||||
task_wait_msg(d);
|
||||
task_wait_event(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "util.h"
|
||||
#include "task.h"
|
||||
#include "thermal.h"
|
||||
#include "timer.h"
|
||||
#include "lpc.h"
|
||||
#include "lpc_commands.h"
|
||||
|
||||
@@ -122,8 +123,7 @@ void pwm_task(void)
|
||||
{
|
||||
while (1) {
|
||||
update_lpc_mapped_memory();
|
||||
/* Wait 1s */
|
||||
task_wait_msg(1000000);
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ void keyboard_scan_task(void)
|
||||
|
||||
while (1) {
|
||||
wait_for_interrupt();
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
|
||||
enter_polling_mode();
|
||||
/* Busy polling keyboard state. */
|
||||
@@ -453,7 +453,7 @@ void keyboard_scan_task(void)
|
||||
|
||||
void matrix_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
task_send_msg(TASK_ID_KEYSCAN, TASK_ID_KEYSCAN, 0);
|
||||
task_wake(TASK_ID_KEYSCAN);
|
||||
}
|
||||
|
||||
int keyboard_has_char()
|
||||
|
||||
@@ -21,7 +21,7 @@ extern const struct console_command __cmds_end[];
|
||||
void console_has_input(void)
|
||||
{
|
||||
/* Wake up the console task */
|
||||
task_send_msg(TASK_ID_CONSOLE, TASK_ID_CONSOLE, 0);
|
||||
task_wake(TASK_ID_CONSOLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ void console_task(void)
|
||||
while (1) {
|
||||
console_process();
|
||||
/* wait for the next command message */
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ static int wait_in_signal(enum gpio_signal signal, int value, int timeout)
|
||||
gpio_get_level(signal) != value) {
|
||||
now = get_time();
|
||||
if ((now.val >= deadline.val) ||
|
||||
(task_wait_msg(deadline.val - now.val) ==
|
||||
(1 << TASK_ID_TIMER))) {
|
||||
(task_wait_event(deadline.val - now.val) ==
|
||||
TASK_EVENT_TIMER)) {
|
||||
uart_printf("Timeout waiting for GPIO %d\n", signal);
|
||||
return EC_ERROR_TIMEOUT;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ static void wait_for_power_off(void)
|
||||
/* wait for power button press or XPSHOLD falling edge */
|
||||
while ((gpio_get_level(GPIO_EC_PWRON) == 0) &&
|
||||
(gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 1)) {
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
}
|
||||
/* XPSHOLD released by AP : shutdown immediatly */
|
||||
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0)
|
||||
@@ -89,8 +89,8 @@ static void wait_for_power_off(void)
|
||||
(gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 1)) {
|
||||
now = get_time();
|
||||
if ((now.val >= deadline.val) ||
|
||||
(task_wait_msg(deadline.val - now.val) ==
|
||||
(1 << TASK_ID_TIMER)))
|
||||
(task_wait_event(deadline.val - now.val) ==
|
||||
TASK_EVENT_TIMER))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ static void wait_for_power_off(void)
|
||||
void gaia_power_event(enum gpio_signal signal)
|
||||
{
|
||||
/* Wake up the task */
|
||||
task_send_msg(TASK_ID_GAIAPOWER, TASK_ID_GAIAPOWER, 0);
|
||||
task_wake(TASK_ID_GAIAPOWER);
|
||||
}
|
||||
|
||||
int gaia_power_init(void)
|
||||
@@ -197,7 +197,7 @@ static int command_force_power(int argc, char **argv)
|
||||
force_signal = GPIO_EC_PWRON;
|
||||
force_value = 1;
|
||||
/* Wake up the task */
|
||||
task_send_msg(TASK_ID_GAIAPOWER, TASK_ID_GAIAPOWER, 0);
|
||||
task_wake(TASK_ID_GAIAPOWER);
|
||||
/* wait 100 ms */
|
||||
usleep(100000);
|
||||
/* release power button */
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "uart.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TASK_EVENT_SLOT(n) TASK_EVENT_CUSTOM(1 << n)
|
||||
|
||||
static int host_command[2];
|
||||
|
||||
/* Host commands are described in a special section */
|
||||
@@ -41,9 +43,8 @@ void host_command_received(int slot, int command)
|
||||
/* Save the command */
|
||||
host_command[slot] = command;
|
||||
|
||||
/* Wake up the task to handle the command. Use the slot as
|
||||
* the task ID. */
|
||||
task_send_msg(TASK_ID_HOSTCMD, slot, 0);
|
||||
/* Wake up the task to handle the command for the slot */
|
||||
task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_SLOT(slot), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,13 +162,12 @@ void host_command_task(void)
|
||||
host_command_init();
|
||||
|
||||
while (1) {
|
||||
/* wait for the next command message */
|
||||
int m = task_wait_msg(-1);
|
||||
/* wait for the next command event */
|
||||
int evt = task_wait_event(-1);
|
||||
/* process it */
|
||||
/* TODO: use message flags to determine which slots */
|
||||
if (m & 0x01)
|
||||
if (evt & TASK_EVENT_SLOT(0))
|
||||
command_process(0);
|
||||
if (m & 0x02)
|
||||
if (evt & TASK_EVENT_SLOT(1))
|
||||
command_process(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ void i8042_command_task(void)
|
||||
{
|
||||
while (1) {
|
||||
/* Either a new byte to host or host picking up can un-block. */
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
|
||||
while (1) {
|
||||
uint8_t chr;
|
||||
@@ -144,7 +144,7 @@ enum ec_error_list i8042_send_to_host(int len, uint8_t *to_host)
|
||||
enq_to_host(len, to_host);
|
||||
|
||||
/* Wake up the task to handle the command */
|
||||
task_send_msg(TASK_ID_I8042CMD, TASK_ID_I8042CMD, 0);
|
||||
task_wake(TASK_ID_I8042CMD);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "task.h"
|
||||
#include "temp_sensor.h"
|
||||
#include "thermal.h"
|
||||
#include "timer.h"
|
||||
#include "tmp006.h"
|
||||
#include "uart.h"
|
||||
#include "util.h"
|
||||
@@ -93,8 +94,7 @@ void temp_sensor_task(void)
|
||||
while (1) {
|
||||
poll_all_sensors();
|
||||
update_lpc_mapped_memory();
|
||||
/* Wait 1s */
|
||||
task_wait_msg(1000000);
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "task.h"
|
||||
#include "temp_sensor.h"
|
||||
#include "thermal.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "util.h"
|
||||
#include "x86_power.h"
|
||||
@@ -193,8 +194,7 @@ void thermal_task(void)
|
||||
{
|
||||
while (1) {
|
||||
thermal_process();
|
||||
/* Wait 1s */
|
||||
task_wait_msg(1000000);
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,13 @@ static void jump_to_other_image(void)
|
||||
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_TASK_KEYSCAN
|
||||
/* Don't jump if recovery requested */
|
||||
if (keyboard_scan_recovery_pressed()) {
|
||||
uart_puts("Vboot staying in RO because key pressed.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Don't jump if we're in RO becuase we jumped there (this keeps us
|
||||
* from jumping to RO only to jump right back). */
|
||||
|
||||
@@ -149,7 +149,7 @@ static int wait_in_signals(uint32_t want)
|
||||
in_want = want;
|
||||
|
||||
while ((in_signals & in_want) != in_want) {
|
||||
if (task_wait_msg(DEFAULT_TIMEOUT) == (1 << TASK_ID_TIMER)) {
|
||||
if (task_wait_event(DEFAULT_TIMEOUT) == TASK_EVENT_TIMER) {
|
||||
update_in_signals();
|
||||
uart_printf("[x86 power timeout on input; "
|
||||
"wanted 0x%04x, got 0x%04x]\n",
|
||||
@@ -240,7 +240,7 @@ void x86_power_interrupt(enum gpio_signal signal)
|
||||
update_in_signals();
|
||||
|
||||
/* Wake up the task */
|
||||
task_send_msg(TASK_ID_X86POWER, TASK_ID_X86POWER, 0);
|
||||
task_wake(TASK_ID_X86POWER);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -426,7 +426,7 @@ void x86_power_task(void)
|
||||
|
||||
/* Otherwise, steady state; wait for a message */
|
||||
in_want = 0;
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
break;
|
||||
|
||||
case X86_S3:
|
||||
@@ -442,7 +442,7 @@ void x86_power_task(void)
|
||||
|
||||
/* Otherwise, steady state; wait for a message */
|
||||
in_want = 0;
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
break;
|
||||
|
||||
case X86_S0:
|
||||
@@ -454,7 +454,7 @@ void x86_power_task(void)
|
||||
|
||||
/* Otherwise, steady state; wait for a message */
|
||||
in_want = 0;
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ static void task_exit_trap(void)
|
||||
uart_printf("[Task %d (%s) exited!]\n", i, task_names[i]);
|
||||
/* Exited tasks simply sleep forever */
|
||||
while (1)
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,15 +198,6 @@ void __schedule(int desched, int resched)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change the task scheduled after returning from the exception.
|
||||
*
|
||||
* If task_send_msg has been called and has set need_resched flag,
|
||||
* we re-compute which task is running and eventually swap the context
|
||||
* saved on the process stack to restore the new one at exception exit.
|
||||
*
|
||||
* it must be called from interrupt context !
|
||||
*/
|
||||
void task_resched_if_needed(void *excep_return)
|
||||
{
|
||||
/**
|
||||
@@ -220,7 +211,7 @@ void task_resched_if_needed(void *excep_return)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t __wait_msg(int timeout_us, task_id_t resched)
|
||||
static uint32_t __wait_evt(int timeout_us, task_id_t resched)
|
||||
{
|
||||
task_ *tsk = __get_current();
|
||||
task_id_t me = tsk - tasks;
|
||||
@@ -247,17 +238,13 @@ static uint32_t __wait_msg(int timeout_us, task_id_t resched)
|
||||
}
|
||||
|
||||
|
||||
uint32_t task_send_msg(task_id_t tskid, task_id_t from, int wait)
|
||||
uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait)
|
||||
{
|
||||
task_ *receiver = __task_id_to_ptr(tskid);
|
||||
ASSERT(receiver);
|
||||
|
||||
if (from == TASK_ID_CURRENT) {
|
||||
from = task_get_current();
|
||||
}
|
||||
|
||||
/* set the event bit in the receiver message bitmap */
|
||||
atomic_or(&receiver->events, 1 << from);
|
||||
atomic_or(&receiver->events, event);
|
||||
|
||||
/* Re-schedule if priorities have changed */
|
||||
if (in_interrupt_context()) {
|
||||
@@ -266,7 +253,7 @@ uint32_t task_send_msg(task_id_t tskid, task_id_t from, int wait)
|
||||
need_resched = 1;
|
||||
} else {
|
||||
if (wait)
|
||||
return __wait_msg(-1, tskid);
|
||||
return __wait_evt(-1, tskid);
|
||||
else
|
||||
__schedule(0, tskid);
|
||||
}
|
||||
@@ -275,9 +262,9 @@ uint32_t task_send_msg(task_id_t tskid, task_id_t from, int wait)
|
||||
}
|
||||
|
||||
|
||||
uint32_t task_wait_msg(int timeout_us)
|
||||
uint32_t task_wait_event(int timeout_us)
|
||||
{
|
||||
return __wait_msg(timeout_us, TASK_ID_IDLE);
|
||||
return __wait_evt(timeout_us, TASK_ID_IDLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +341,7 @@ void mutex_lock(struct mutex *mtx)
|
||||
*/
|
||||
if (value == 2) {
|
||||
/* contention on the mutex */
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
}
|
||||
} while (value);
|
||||
|
||||
@@ -374,11 +361,11 @@ void mutex_unlock(struct mutex *mtx)
|
||||
while (waiters) {
|
||||
task_id_t id = 31 - __builtin_clz(waiters);
|
||||
/* somebody is waiting on the mutex */
|
||||
task_send_msg(id, TASK_ID_MUTEX, 0);
|
||||
task_set_event(id, TASK_EVENT_MUTEX, 0);
|
||||
waiters &= ~(1 << id);
|
||||
}
|
||||
/* Ensure no event is remaining from mutex wake-up */
|
||||
atomic_clear(&tsk->events, 1 << TASK_ID_MUTEX);
|
||||
atomic_clear(&tsk->events, TASK_EVENT_MUTEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ static void expire_timer(task_id_t tskid)
|
||||
/* we are done with this timer */
|
||||
atomic_clear(&timer_running, 1<<tskid);
|
||||
/* wake up the taks waiting for this timer */
|
||||
task_send_msg(tskid, TASK_ID_TIMER, 0);
|
||||
task_set_event(tskid, TASK_EVENT_TIMER, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,12 +130,12 @@ void usleep(unsigned us)
|
||||
uint32_t evt = 0;
|
||||
ASSERT(us);
|
||||
do {
|
||||
evt |= task_wait_msg(us);
|
||||
} while (!(evt & (1 << TASK_ID_TIMER)));
|
||||
evt |= task_wait_event(us);
|
||||
} while (!(evt & TASK_EVENT_TIMER));
|
||||
/* re-queue other events which happened in the meanwhile */
|
||||
if (evt)
|
||||
atomic_or(task_get_event_bitmap(task_get_current()),
|
||||
evt & ~(1 << TASK_ID_TIMER));
|
||||
evt & ~TASK_EVENT_TIMER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
@@ -11,66 +11,72 @@
|
||||
#include "common.h"
|
||||
#include "task_id.h"
|
||||
|
||||
/* Disables CPU interrupt bit. This might break the system so think really hard
|
||||
/* Task event bitmasks */
|
||||
#define TASK_EVENT_CUSTOM(x) (x & 0x1fffffff)
|
||||
#define TASK_EVENT_WAKE (1 << 29) /* task_wake() called on task */
|
||||
#define TASK_EVENT_MUTEX (1 << 30) /* Mutex unlocking */
|
||||
#define TASK_EVENT_TIMER (1 << 31) /* Timer expired. For example,
|
||||
* task_wait_event() timed out before
|
||||
* receiving another event. */
|
||||
|
||||
/* Disable CPU interrupt bit. This might break the system so think really hard
|
||||
* before using these. There are usually better ways of accomplishing this. */
|
||||
void interrupt_disable(void);
|
||||
|
||||
/* Enables CPU interrupt */
|
||||
/* Enable CPU interrupt bit. */
|
||||
void interrupt_enable(void);
|
||||
|
||||
/**
|
||||
* Return true if we are in interrupt context
|
||||
*/
|
||||
/* Return true if we are in interrupt context. */
|
||||
inline int in_interrupt_context(void);
|
||||
|
||||
/**
|
||||
* Send a message to a task and wake it up if it is higher priority than us
|
||||
/* Set an event for task <tskid> and wake it up if it is higher priority than
|
||||
* the current task.
|
||||
*
|
||||
* tskid : identifier of the receiver task
|
||||
* from : identifier of the sender of the message
|
||||
* wait : after sending, de-schedule the calling task to wait for the answer
|
||||
* event : event bitmap to set (TASK_EVENT_*)
|
||||
*
|
||||
* returns the bitmap of events which have occured.
|
||||
* If wait!=0, after setting the event, de-schedule the calling task to wait
|
||||
* for a response event, then return the bitmap of events which have occured
|
||||
* (same as task_wait_event()). Ignored in interrupt context.
|
||||
*
|
||||
* Can be called both in interrupt context and task context.
|
||||
*/
|
||||
uint32_t task_send_msg(task_id_t tskid, task_id_t from, int wait);
|
||||
* If wait==0, returns 0.
|
||||
*
|
||||
* Can be called both in interrupt context and task context. */
|
||||
uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait);
|
||||
|
||||
/**
|
||||
* Return the identifier of the task currently running
|
||||
/* Wake a task. This sends it the TASK_EVENT_WAKE event. */
|
||||
static inline void task_wake(task_id_t tskid)
|
||||
{
|
||||
task_set_event(tskid, TASK_EVENT_WAKE, 0);
|
||||
}
|
||||
|
||||
/* Return the identifier of the task currently running.
|
||||
*
|
||||
* when called in interrupt context, returns TASK_ID_INVALID
|
||||
*/
|
||||
* When called in interrupt context, returns TASK_ID_INVALID. */
|
||||
task_id_t task_get_current(void);
|
||||
|
||||
/**
|
||||
* Return a pointer to the bitmap of received events of the task.
|
||||
*/
|
||||
/* Return a pointer to the bitmap of events of the task. */
|
||||
uint32_t *task_get_event_bitmap(task_id_t tsk);
|
||||
|
||||
/**
|
||||
* Waits for the incoming next message.
|
||||
/* Wait for the next event.
|
||||
*
|
||||
* if an event is already pending, it returns it immediatly, else it
|
||||
* de-schedules the calling task and wake up the next one in the priority order
|
||||
* If one or more events are already pending, returns immediately. Otherwise,
|
||||
* it de-schedules the calling task and wakes up the next one in the priority
|
||||
* order.
|
||||
*
|
||||
* if timeout_us > 0, it also sets a timer to produce an event after the
|
||||
* specified micro-second duration.
|
||||
* If timeout_us > 0, it also sets a timer to produce the TASK_EVENT_TIMER
|
||||
* event after the specified micro-second duration.
|
||||
*
|
||||
* returns the bitmap of received events (and clear it atomically).
|
||||
*/
|
||||
uint32_t task_wait_msg(int timeout_us);
|
||||
* Returns the bitmap of received events (and clears it atomically). */
|
||||
uint32_t task_wait_event(int timeout_us);
|
||||
|
||||
/**
|
||||
* Changes the task scheduled after returning from the exception.
|
||||
/* Change the task scheduled after returning from the exception.
|
||||
*
|
||||
* If task_send_msg has been called and has set need_resched flag,
|
||||
* we re-compute which task is running and eventually swap the context
|
||||
* If task_send_event() has been called and has set need_resched flag,
|
||||
* re-computes which task is running and eventually swaps the context
|
||||
* saved on the process stack to restore the new one at exception exit.
|
||||
*
|
||||
* it must be called from interrupt context !
|
||||
* and it is designed to be the last call of the interrupt handler.
|
||||
*/
|
||||
* This must be called from interrupt context(!) and is designed to be the
|
||||
* last call of the interrupt handler. */
|
||||
void task_resched_if_needed(void *excep_return);
|
||||
|
||||
/* Initializes tasks and interrupt controller. */
|
||||
@@ -93,12 +99,10 @@ struct mutex {
|
||||
uint32_t waiters;
|
||||
};
|
||||
|
||||
/**
|
||||
* try to lock the mutex mtx
|
||||
* and de-schedule the task if it is already locked by another task.
|
||||
/* Try to lock the mutex mtx and de-schedule the current task if mtx is already
|
||||
* locked by another task.
|
||||
*
|
||||
* Should not be used in interrupt context !
|
||||
*/
|
||||
* Must not be used in interrupt context! */
|
||||
void mutex_lock(struct mutex *mtx);
|
||||
|
||||
/* Release a mutex previously locked by the same task. */
|
||||
@@ -113,10 +117,8 @@ struct irq_priority {
|
||||
#define IRQ_BUILD_NAME(prefix, irqnum, postfix) prefix ## irqnum ## postfix
|
||||
#define IRQ_HANDLER(irqname) IRQ_BUILD_NAME(irq_,irqname,_handler)
|
||||
|
||||
/**
|
||||
* Connects the interrupt handler "routine" to the irq number "irq" and
|
||||
* ensures it is enabled in the interrupt controller with the right priority.
|
||||
*/
|
||||
/* Connects the interrupt handler "routine" to the irq number "irq" and ensures
|
||||
* it is enabled in the interrupt controller with the right priority. */
|
||||
#define DECLARE_IRQ(irq, routine, priority) \
|
||||
void IRQ_HANDLER(irq)(void) \
|
||||
{ \
|
||||
|
||||
@@ -32,9 +32,6 @@ enum {
|
||||
/* Number of tasks */
|
||||
TASK_ID_COUNT,
|
||||
/* Special task identifiers */
|
||||
TASK_ID_MUTEX = 0x1e, /* signal mutex unlocking */
|
||||
TASK_ID_TIMER = 0x1f, /* message from an expired timer */
|
||||
TASK_ID_CURRENT = 0xfe, /* the currently running task */
|
||||
TASK_ID_INVALID = 0xff /* unable to find the task */
|
||||
};
|
||||
#undef TASK
|
||||
|
||||
20
test/mutex.c
20
test/mutex.c
@@ -30,16 +30,16 @@ int mutex_random_task(void *unused)
|
||||
/* wait to be activated */
|
||||
|
||||
while (1) {
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
uart_printf("%c+\n", letter);
|
||||
mutex_lock(&mtx);
|
||||
uart_printf("%c=\n", letter);
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
uart_printf("%c-\n", letter);
|
||||
mutex_unlock(&mtx);
|
||||
}
|
||||
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
@@ -50,15 +50,15 @@ int mutex_second_task(void *unused)
|
||||
|
||||
uart_printf("\n[Mutex second task %d]\n", id);
|
||||
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
uart_printf("MTX2: locking...");
|
||||
mutex_lock(&mtx);
|
||||
uart_printf("done\n");
|
||||
task_send_msg(TASK_ID_MTX1, 1, 0);
|
||||
task_wake(TASK_ID_MTX1);
|
||||
uart_printf("MTX2: unlocking...\n");
|
||||
mutex_unlock(&mtx);
|
||||
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ int mutex_main_task(void *unused)
|
||||
/* --- Serialization to test simple contention --- */
|
||||
uart_printf("Simple contention :\n");
|
||||
/* lock the mutex from the other task */
|
||||
task_send_msg(TASK_ID_MTX2, 1, 1);
|
||||
task_set_event(TASK_ID_MTX2, TASK_EVENT_WAKE, 1);
|
||||
/* block on the mutex */
|
||||
uart_printf("MTX1: blocking...\n");
|
||||
mutex_lock(&mtx);
|
||||
@@ -96,17 +96,17 @@ int mutex_main_task(void *unused)
|
||||
uart_printf("Massive locking/unlocking :\n");
|
||||
for (i = 0; i < 500; i++) {
|
||||
/* Wake up a random task */
|
||||
task_send_msg(RANDOM_TASK(rtask), 1, 0);
|
||||
task_wake(RANDOM_TASK(rtask));
|
||||
/* next pseudo random delay */
|
||||
rtask = prng(rtask);
|
||||
/* Wait for a "random" period */
|
||||
task_wait_msg(PERIOD_US(rdelay));
|
||||
task_wait_event(PERIOD_US(rdelay));
|
||||
/* next pseudo random delay */
|
||||
rdelay = prng(rdelay);
|
||||
}
|
||||
|
||||
uart_printf("Test done.\n");
|
||||
task_wait_msg(0);
|
||||
task_wait_event(0);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Tasks for scheduling test.
|
||||
*/
|
||||
@@ -24,7 +23,7 @@ int TaskAbc(void *data)
|
||||
while (1) {
|
||||
uart_puts(string);
|
||||
uart_flush_output();
|
||||
task_send_msg(next, TASK_ID_CURRENT, 1);
|
||||
task_set_event(next, TASK_EVENT_WAKE, 1);
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
@@ -180,7 +180,7 @@ int power_demo_task(void)
|
||||
power_demo_init();
|
||||
|
||||
/* suspend this task forever */
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Tasks for scheduling test.
|
||||
*/
|
||||
@@ -35,7 +34,7 @@ int timer_calib_task(void *data)
|
||||
usleep(1000000);
|
||||
t1 = get_time();
|
||||
uart_printf("done. delay = %d us\n", difftime(t0, t1));
|
||||
|
||||
|
||||
/* try small usleep */
|
||||
uart_printf("- short sleep :\n");
|
||||
uart_flush_output();
|
||||
@@ -49,7 +48,7 @@ int timer_calib_task(void *data)
|
||||
|
||||
uart_printf("Done.\n");
|
||||
/* sleep forever */
|
||||
task_wait_msg(-1);
|
||||
task_wait_event(-1);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Tasks for timer test.
|
||||
*/
|
||||
@@ -29,7 +28,7 @@ int TaskTimer(void *seed)
|
||||
|
||||
while (1) {
|
||||
/* Wait for a "random" period */
|
||||
task_wait_msg(PERIOD_US(num));
|
||||
task_wait_event(PERIOD_US(num));
|
||||
uart_printf("%01d\n", id);
|
||||
/* next pseudo random delay */
|
||||
num = prng(num);
|
||||
|
||||
Reference in New Issue
Block a user