1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 01:53:51 +01:00
2025-05-28 21:02:27 +02:00

113 lines
2.6 KiB
C

/*
* Copyright (C) 2025 ML!PA Consulting GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief thread flags group test application
*
* @author Mihai Renea <mihai.renea@ml-pa.com>
*
* @}
*/
#include <stdio.h>
#include "atomic_utils.h"
#include "test_utils/expect.h"
#include "thread.h"
#include "thread_flags_group.h"
#ifndef WAITER_THREADS_CNT
# define WAITER_THREADS_CNT 3
#endif
#ifdef CPU_NATIVE
# define WAITER_STACKSIZE THREAD_STACKSIZE_MAIN
#else
# define WAITER_STACKSIZE THREAD_STACKSIZE_SMALL
#endif
static char stacks[WAITER_THREADS_CNT][WAITER_STACKSIZE];
#define GOOD_FLAG 0x2
#define BAD_FLAG 0x4
static uint8_t woken_up = 0;
static uint8_t last_prio = 0;
static thread_flags_group_t group = THREAD_FLAGS_GROUP_INIT;
static void _print_waiting(char const *what_who, kernel_pid_t pid)
{
#ifdef CPU_NATIVE
printf("%s %d\n", what_who, pid);
#else
puts(what_who);
(void)pid;
#endif
}
static void *forever_waiter(void *arg)
{
_print_waiting("waiting forever-waiter", (kernel_pid_t)(uintptr_t)arg);
thread_flags_wait_any(GOOD_FLAG | BAD_FLAG);
expect(false);
}
static void *waiter(void *arg)
{
thread_flags_group_join(&group);
_print_waiting("waiting waiter", (kernel_pid_t)(uintptr_t)arg);
thread_flags_wait_any(GOOD_FLAG);
_print_waiting("woken up waiter", (kernel_pid_t)(uintptr_t)arg);
expect(atomic_load_u8(&last_prio) <= thread_get_active()->priority);
atomic_store_u8(&last_prio, thread_get_active()->priority);
atomic_fetch_add_u8(&woken_up, 1);
return NULL;
}
int main(void)
{
puts("START");
unsigned waiters_cnt = 0;
for (unsigned i = 0; i < WAITER_THREADS_CNT; i++) {
int prio = (int)THREAD_PRIORITY_MAIN - i - 1;
if (prio < 0) {
prio = 0;
}
thread_task_func_t handler = i % 3 ? (waiters_cnt++, waiter) : forever_waiter;
int res = thread_create(stacks[i], sizeof(stacks[0]),
prio, THREAD_CREATE_STACKTEST, handler,
(void *)(uintptr_t)i, "waiter");
expect(res >= 0);
}
/* this shouldn't wake up */
thread_flags_group_set(&group, BAD_FLAG);
expect(atomic_load_u8(&woken_up) == 0);
puts("waking up!");
thread_flags_group_set(&group, GOOD_FLAG);
/* waiters have higher prio, so they must have finished */
expect(atomic_load_u8(&woken_up) == waiters_cnt);
puts("SUCCESS");
return 0;
}