mirror of
https://github.com/google/pebble.git
synced 2025-03-22 03:32:20 +00:00
142 lines
4 KiB
C
142 lines
4 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "services/common/system_task.h"
|
|
#include "fake_pebble_tasks.h"
|
|
|
|
#include "util/list.h"
|
|
|
|
#include "clar_asserts.h"
|
|
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
typedef struct {
|
|
ListNode node;
|
|
SystemTaskEventCallback callback;
|
|
void *data;
|
|
} SystemTaskCallbackNode;
|
|
|
|
static ListNode *s_system_task_callback_head = NULL;
|
|
static bool s_invoke_as_current = false;
|
|
static uint32_t system_task_available_space = ~(uint32_t)0;
|
|
|
|
bool system_task_add_callback(SystemTaskEventCallback cb, void *data) {
|
|
SystemTaskCallbackNode *node = (SystemTaskCallbackNode *) malloc(sizeof(SystemTaskCallbackNode));
|
|
cl_assert(node != NULL);
|
|
list_init(&node->node);
|
|
|
|
cl_assert(cb);
|
|
node->callback = cb;
|
|
node->data = data;
|
|
|
|
s_system_task_callback_head = list_prepend(s_system_task_callback_head, &node->node);
|
|
cl_assert(s_system_task_callback_head);
|
|
system_task_available_space--;
|
|
return true;
|
|
}
|
|
|
|
bool system_task_add_callback_from_isr(SystemTaskEventCallback cb, void *data,
|
|
bool *should_context_switch) {
|
|
*should_context_switch = false;
|
|
return system_task_add_callback(cb, data);
|
|
}
|
|
|
|
uint32_t system_task_get_available_space(void) {
|
|
return system_task_available_space;
|
|
}
|
|
|
|
void system_task_set_available_space(uint32_t space) {
|
|
system_task_available_space = space;
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// Stub:
|
|
//
|
|
void stub_invoke_system_task_as_current(void) {
|
|
s_invoke_as_current = !s_invoke_as_current;
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// Fake manipulation:
|
|
//
|
|
void *s_fake_system_task_current_cb;
|
|
|
|
void fake_system_task_callbacks_invoke(int num_to_invoke) {
|
|
PebbleTask current_task = pebble_task_get_current();
|
|
if (!s_invoke_as_current) {
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
}
|
|
|
|
// Start at tail ("oldest" callback):
|
|
SystemTaskCallbackNode *node = (SystemTaskCallbackNode *) list_get_tail(s_system_task_callback_head);
|
|
while (node && num_to_invoke) {
|
|
// do callback first, in case callback enqueues more callbacks
|
|
if (node->callback) {
|
|
s_fake_system_task_current_cb = node->callback;
|
|
node->callback(node->data);
|
|
s_fake_system_task_current_cb = NULL;
|
|
}
|
|
SystemTaskCallbackNode *prev = (SystemTaskCallbackNode *) list_get_prev(&node->node);
|
|
list_remove(&node->node, &s_system_task_callback_head, NULL);
|
|
free(node);
|
|
node = prev;
|
|
|
|
system_task_available_space++;
|
|
num_to_invoke--;
|
|
}
|
|
|
|
stub_pebble_tasks_set_current(current_task);
|
|
}
|
|
|
|
void fake_system_task_callbacks_invoke_pending(void) {
|
|
// sometimes the cb's may add new jobs so we need to keep looping until no
|
|
// more are left
|
|
while (s_system_task_callback_head) {
|
|
fake_system_task_callbacks_invoke(list_count(s_system_task_callback_head));
|
|
}
|
|
}
|
|
|
|
void fake_system_task_callbacks_cleanup(void) {
|
|
SystemTaskCallbackNode *node = (SystemTaskCallbackNode *) s_system_task_callback_head;
|
|
while (node) {
|
|
SystemTaskCallbackNode *next = (SystemTaskCallbackNode *) list_get_next(&node->node);
|
|
list_remove(&node->node, &s_system_task_callback_head, NULL);
|
|
free(node);
|
|
node = next;
|
|
}
|
|
cl_assert(s_system_task_callback_head == NULL);
|
|
}
|
|
|
|
void system_task_watchdog_feed(void) {
|
|
}
|
|
|
|
uint32_t fake_system_task_count_callbacks(void) {
|
|
return list_count(s_system_task_callback_head);
|
|
}
|
|
|
|
void system_task_enable_raised_priority(bool is_raised) {
|
|
}
|
|
|
|
bool system_task_is_ready_to_run(void) {
|
|
return true;
|
|
}
|
|
|
|
void* system_task_get_current_callback(void) {
|
|
return s_fake_system_task_current_cb;
|
|
}
|