Merge pull request #8993 from ZetaR60/RIOT_cbmplex
sys/cb_mux: Callback multiplexer
This commit is contained in:
commit
657bd25dbe
1
sys/cb_mux/Makefile
Normal file
1
sys/cb_mux/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
124
sys/cb_mux/cb_mux.c
Normal file
124
sys/cb_mux/cb_mux.c
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
*
|
||||||
|
* 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 sys_cb_mux
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief cb_mux implementation
|
||||||
|
*
|
||||||
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cb_mux.h"
|
||||||
|
#include "utlist.h"
|
||||||
|
|
||||||
|
void cb_mux_add(cb_mux_t **head, cb_mux_t *entry)
|
||||||
|
{
|
||||||
|
LL_APPEND(*head, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cb_mux_del(cb_mux_t **head, cb_mux_t *entry)
|
||||||
|
{
|
||||||
|
LL_DELETE(*head, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_mux_t *cb_mux_find_cbid(cb_mux_t *head, cb_mux_cbid_t cbid_val)
|
||||||
|
{
|
||||||
|
cb_mux_t *entry;
|
||||||
|
|
||||||
|
LL_SEARCH_SCALAR(head, entry, cbid, cbid_val);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_mux_t *cb_mux_find_low(cb_mux_t *head)
|
||||||
|
{
|
||||||
|
cb_mux_t *entry;
|
||||||
|
cb_mux_t *entry_low = NULL;
|
||||||
|
cb_mux_cbid_t id = (cb_mux_cbid_t)(-1);
|
||||||
|
|
||||||
|
LL_FOREACH(head, entry) {
|
||||||
|
/* Entry does not have lower ID */
|
||||||
|
if (entry->cbid >= id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = entry->cbid;
|
||||||
|
entry_low = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_mux_t *cb_mux_find_high(cb_mux_t *head)
|
||||||
|
{
|
||||||
|
cb_mux_t *entry;
|
||||||
|
cb_mux_t *entry_high = NULL;
|
||||||
|
cb_mux_cbid_t id = 0;
|
||||||
|
|
||||||
|
LL_FOREACH(head, entry) {
|
||||||
|
/* Entry does not have higher ID */
|
||||||
|
if (entry->cbid <= id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = entry->cbid;
|
||||||
|
entry_high = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry_high;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_mux_cbid_t cb_mux_find_free_id(cb_mux_t *head)
|
||||||
|
{
|
||||||
|
uint32_t free;
|
||||||
|
cb_mux_cbid_t block;
|
||||||
|
cb_mux_t *entry;
|
||||||
|
uint8_t num;
|
||||||
|
|
||||||
|
/* Search for free IDs in blocks of 32 IDs */
|
||||||
|
for (block = 0; block + 31 < (cb_mux_cbid_t)(-1); block += 32) {
|
||||||
|
/* Set all IDs in block to free */
|
||||||
|
free = 0;
|
||||||
|
|
||||||
|
LL_FOREACH(head, entry) {
|
||||||
|
/* cbid falls within this block */
|
||||||
|
if ((entry->cbid >= block) && (entry->cbid < block + 32)) {
|
||||||
|
/* Set cbid to taken */
|
||||||
|
free |= 1 << (entry->cbid & 0x1F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At least one ID in block free */
|
||||||
|
if (~free) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find which ID in block was free */
|
||||||
|
for (num = 0; num < 32; num++) {
|
||||||
|
if (~free & (1 << num)) {
|
||||||
|
return block | num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No free IDs */
|
||||||
|
return (cb_mux_cbid_t)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cb_mux_iter(cb_mux_t *head, cb_mux_iter_t func, void *arg)
|
||||||
|
{
|
||||||
|
cb_mux_t *entry;
|
||||||
|
|
||||||
|
LL_FOREACH(head, entry) {
|
||||||
|
func(entry, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
143
sys/include/cb_mux.h
Normal file
143
sys/include/cb_mux.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sys_cb_mux Callback multiplexer
|
||||||
|
* @ingroup sys
|
||||||
|
* @brief cb_mux provides utilities for storing, retrieving, and managing
|
||||||
|
* callback information in a singly linked list.
|
||||||
|
*
|
||||||
|
* If an API provides the ability to call multiple callbacks, cb_mux can
|
||||||
|
* simplify handling of an arbitrary number of callbacks by requiring memory
|
||||||
|
* for a cb_mux entry to be passed along with other arguments. The cb_mux entry
|
||||||
|
* is then attached to a list using cb_mux_add. The code implementing that API
|
||||||
|
* can manage the list using the various utility functions that cb_mux provides.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief cb_mux interface definitions
|
||||||
|
*
|
||||||
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CB_MUX_H
|
||||||
|
#define CB_MUX_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* For alternate cb_mux_cbid_t */
|
||||||
|
#include "periph_cpu.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_CB_MUX_CBID_T
|
||||||
|
/**
|
||||||
|
* @brief cb_mux identifier type
|
||||||
|
*/
|
||||||
|
typedef unsigned int cb_mux_cbid_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cb_mux callback type
|
||||||
|
*/
|
||||||
|
typedef void (*cb_mux_cb_t)(void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cb_mux list entry structure
|
||||||
|
*/
|
||||||
|
typedef struct cb_mux {
|
||||||
|
struct cb_mux *next; /**< next entry in the cb_mux list */
|
||||||
|
cb_mux_cbid_t cbid; /**< identifier for this callback */
|
||||||
|
void *info; /**< optional extra information */
|
||||||
|
cb_mux_cb_t cb; /**< callback function */
|
||||||
|
void *arg; /**< argument for callback function */
|
||||||
|
} cb_mux_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cb_mux iterate function callback type for cb_mux_iter
|
||||||
|
*/
|
||||||
|
typedef void (*cb_mux_iter_t)(cb_mux_t *, void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a new entry to the end of a cb_mux list
|
||||||
|
*
|
||||||
|
* @param[in] head double pointer to first list entry
|
||||||
|
* @param[in] entry entry to add
|
||||||
|
*/
|
||||||
|
void cb_mux_add(cb_mux_t **head, cb_mux_t *entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a entry from a cb_mux list
|
||||||
|
*
|
||||||
|
* @param[in] head double pointer to first list entry
|
||||||
|
* @param[in] entry entry to remove
|
||||||
|
*/
|
||||||
|
void cb_mux_del(cb_mux_t **head, cb_mux_t *entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find an entry in the list by ID
|
||||||
|
*
|
||||||
|
* @param[in] head pointer to first list entry
|
||||||
|
* @param[in] cbid_val ID to find
|
||||||
|
*
|
||||||
|
* @return pointer to the list entry
|
||||||
|
*/
|
||||||
|
cb_mux_t *cb_mux_find_cbid(cb_mux_t *head, cb_mux_cbid_t cbid_val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the entry with the lowest ID
|
||||||
|
*
|
||||||
|
* If there are multiple hits, this returns the oldest.
|
||||||
|
*
|
||||||
|
* @param[in] head pointer to first list entry
|
||||||
|
*
|
||||||
|
* @return pointer to the list entry
|
||||||
|
*/
|
||||||
|
cb_mux_t *cb_mux_find_low(cb_mux_t *head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the entry with the highest ID
|
||||||
|
*
|
||||||
|
* If there are multiple hits, this returns the oldest.
|
||||||
|
*
|
||||||
|
* @param[in] head pointer to first list entry
|
||||||
|
*
|
||||||
|
* @return pointer to the list entry
|
||||||
|
*/
|
||||||
|
cb_mux_t *cb_mux_find_high(cb_mux_t *head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the lowest unused ID
|
||||||
|
*
|
||||||
|
* Returns highest possible ID on failure
|
||||||
|
*
|
||||||
|
* @param[in] head pointer to first list entry
|
||||||
|
*
|
||||||
|
* @return lowest unused ID
|
||||||
|
*/
|
||||||
|
cb_mux_cbid_t cb_mux_find_free_id(cb_mux_t *head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Run a function on every item in the cb_mux list
|
||||||
|
*
|
||||||
|
* @param[in] head pointer to first list entry
|
||||||
|
* @param[in] func function to run on each entry
|
||||||
|
* @param[in] arg argument for the function
|
||||||
|
*/
|
||||||
|
void cb_mux_iter(cb_mux_t *head, cb_mux_iter_t func, void *arg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* CB_MUX_H */
|
||||||
10
tests/cb_mux/Makefile
Normal file
10
tests/cb_mux/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
USEMODULE += cb_mux
|
||||||
|
|
||||||
|
TEST_ON_CI_WHITELIST += all
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
|
||||||
|
test:
|
||||||
|
./tests/01-run.py
|
||||||
135
tests/cb_mux/main.c
Normal file
135
tests/cb_mux/main.c
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
*
|
||||||
|
* 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 cb_mux test application
|
||||||
|
*
|
||||||
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "cb_mux.h"
|
||||||
|
|
||||||
|
/* Head of cb_mux list */
|
||||||
|
cb_mux_t *cb_mux_head;
|
||||||
|
|
||||||
|
/* Flags for mux_iter */
|
||||||
|
enum {
|
||||||
|
ITER_TEST = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function to iterate over cb_mux list */
|
||||||
|
void mux_iter(cb_mux_t *entry, void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
entry->info = (void *)((uintptr_t)entry->info | (1 << ITER_TEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test callback */
|
||||||
|
void cb(void *arg)
|
||||||
|
{
|
||||||
|
printf("Callback %u executed\n", (uint8_t)(uintptr_t)arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
cb_mux_t entries[5];
|
||||||
|
cb_mux_cbid_t num;
|
||||||
|
cb_mux_t *entry;
|
||||||
|
|
||||||
|
puts("cb_mux test routine");
|
||||||
|
|
||||||
|
for (num = 0; num < 5; num++) {
|
||||||
|
entries[num].cb = cb;
|
||||||
|
entries[num].arg = (void *)num;
|
||||||
|
entries[num].cbid = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Test list addition, retrieval, execution of 5 CBs");
|
||||||
|
|
||||||
|
for (num = 0; num < 5; num++) {
|
||||||
|
cb_mux_add(&cb_mux_head, &(entries[num]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (num = 0; num < 5; num++) {
|
||||||
|
entry = cb_mux_find_cbid(cb_mux_head, num);
|
||||||
|
|
||||||
|
if (entry->cb == NULL) {
|
||||||
|
puts("[FAILED] Unexpected NULL pointer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->cb(entry->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Test list deletion of CB 0, 2, 4, execution of 1, 3");
|
||||||
|
|
||||||
|
cb_mux_del(&cb_mux_head, &(entries[0]));
|
||||||
|
cb_mux_del(&cb_mux_head, &(entries[2]));
|
||||||
|
cb_mux_del(&cb_mux_head, &(entries[4]));
|
||||||
|
|
||||||
|
for (num = 0; num < 5; num++) {
|
||||||
|
entry = cb_mux_find_cbid(cb_mux_head, num);
|
||||||
|
|
||||||
|
if (entry == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->cb(entry->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Test execution of CB with lowest ID (1)");
|
||||||
|
|
||||||
|
entry = cb_mux_find_low(cb_mux_head);
|
||||||
|
if (entry->cb == NULL) {
|
||||||
|
puts("[FAILED] Unexpected NULL pointer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
entry->cb(entry->arg);
|
||||||
|
|
||||||
|
puts("Test execution of CB with highest ID (3)");
|
||||||
|
|
||||||
|
entry = cb_mux_find_high(cb_mux_head);
|
||||||
|
if (entry->cb == NULL) {
|
||||||
|
puts("[FAILED] Unexpected NULL pointer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
entry->cb(entry->arg);
|
||||||
|
|
||||||
|
puts("Re-adding list entries (0, 2, 4) by finding next free ID");
|
||||||
|
|
||||||
|
num = cb_mux_find_free_id(cb_mux_head);
|
||||||
|
while (num < 5) {
|
||||||
|
cb_mux_add(&cb_mux_head, &(entries[num]));
|
||||||
|
|
||||||
|
printf("Added entry %i\n", num);
|
||||||
|
|
||||||
|
num = cb_mux_find_free_id(cb_mux_head);
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Test iteration of a function over list");
|
||||||
|
|
||||||
|
cb_mux_iter(cb_mux_head, mux_iter, NULL);
|
||||||
|
|
||||||
|
for (num = 0; num < 5; num++) {
|
||||||
|
if ((uintptr_t)entries[num].info & (1 << ITER_TEST)) {
|
||||||
|
printf("Entry %i was updated correctly\n", num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Tests complete!");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
44
tests/cb_mux/tests/01-run.py
Executable file
44
tests/cb_mux/tests/01-run.py
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def testfunc(child):
|
||||||
|
child.expect_exact("cb_mux test routine")
|
||||||
|
child.expect_exact("Test list addition, retrieval, execution of 5 CBs")
|
||||||
|
child.expect_exact("Callback 0 executed")
|
||||||
|
child.expect_exact("Callback 1 executed")
|
||||||
|
child.expect_exact("Callback 2 executed")
|
||||||
|
child.expect_exact("Callback 3 executed")
|
||||||
|
child.expect_exact("Callback 4 executed")
|
||||||
|
child.expect_exact("Test list deletion of CB 0, 2, 4, execution of 1, 3")
|
||||||
|
child.expect_exact("Callback 1 executed")
|
||||||
|
child.expect_exact("Callback 3 executed")
|
||||||
|
child.expect_exact("Test execution of CB with lowest ID (1)")
|
||||||
|
child.expect_exact("Callback 1 executed")
|
||||||
|
child.expect_exact("Test execution of CB with highest ID (3)")
|
||||||
|
child.expect_exact("Callback 3 executed")
|
||||||
|
child.expect_exact("Re-adding list entries (0, 2, 4) by finding next free ID")
|
||||||
|
child.expect_exact("Added entry 0")
|
||||||
|
child.expect_exact("Added entry 2")
|
||||||
|
child.expect_exact("Added entry 4")
|
||||||
|
child.expect_exact("Test iteration of a function over list")
|
||||||
|
child.expect_exact("Entry 0 was updated correctly")
|
||||||
|
child.expect_exact("Entry 1 was updated correctly")
|
||||||
|
child.expect_exact("Entry 2 was updated correctly")
|
||||||
|
child.expect_exact("Entry 3 was updated correctly")
|
||||||
|
child.expect_exact("Entry 4 was updated correctly")
|
||||||
|
child.expect_exact("Tests complete!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
|
||||||
|
from testrunner import run
|
||||||
|
sys.exit(run(testfunc))
|
||||||
11
tests/cb_mux_bench/Makefile
Normal file
11
tests/cb_mux_bench/Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
USEMODULE += cb_mux \
|
||||||
|
xtimer
|
||||||
|
|
||||||
|
TEST_ON_CI_WHITELIST += all
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
|
||||||
|
test:
|
||||||
|
./tests/01-run.py
|
||||||
90
tests/cb_mux_bench/main.c
Normal file
90
tests/cb_mux_bench/main.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
*
|
||||||
|
* 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 cb_mux benchmark application
|
||||||
|
*
|
||||||
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "cb_mux.h"
|
||||||
|
#include "xtimer.h"
|
||||||
|
|
||||||
|
/* Number of entries in the cb_mux list */
|
||||||
|
#define NUM_ENTRIES (20U)
|
||||||
|
|
||||||
|
/* Fail if us greater than threshold */
|
||||||
|
#define FAIL_THRESH (200UL)
|
||||||
|
|
||||||
|
/* Head of cb_mux list */
|
||||||
|
cb_mux_t *cb_mux_head;
|
||||||
|
|
||||||
|
/* cb_mux list entries */
|
||||||
|
cb_mux_t entries[NUM_ENTRIES];
|
||||||
|
|
||||||
|
/* Timing */
|
||||||
|
unsigned long time_prev, time_curr;
|
||||||
|
|
||||||
|
void cb(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
time_curr = xtimer_now_usec();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
unsigned long xtimer_delay, time_diff;
|
||||||
|
uint8_t num;
|
||||||
|
cb_mux_t *entry;
|
||||||
|
|
||||||
|
puts("cb_mux benchmark application");
|
||||||
|
|
||||||
|
/* Delay due to fetching timer with xtimer */
|
||||||
|
time_prev = xtimer_now_usec();
|
||||||
|
xtimer_delay = time_prev - xtimer_now_usec();
|
||||||
|
|
||||||
|
/* Test for worst case: finding last entry */
|
||||||
|
entries[NUM_ENTRIES - 1].cbid = 1;
|
||||||
|
|
||||||
|
printf("Populating cb_mux list with %u items\n", NUM_ENTRIES);
|
||||||
|
|
||||||
|
for (num = 0; num < NUM_ENTRIES; num++) {
|
||||||
|
entries[num].cb = cb;
|
||||||
|
cb_mux_add(&cb_mux_head, &(entries[num]));
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Finding the last list entry");
|
||||||
|
|
||||||
|
time_prev = xtimer_now_usec();
|
||||||
|
|
||||||
|
entry = cb_mux_find_cbid(cb_mux_head, 1);
|
||||||
|
entry->cb(entry->arg);
|
||||||
|
|
||||||
|
time_diff = time_curr - time_prev - xtimer_delay;
|
||||||
|
|
||||||
|
printf("List walk time: %lu us\n", time_diff);
|
||||||
|
|
||||||
|
if (time_diff > FAIL_THRESH) {
|
||||||
|
printf("Walk time greater than threshold of %lu us\n", FAIL_THRESH);
|
||||||
|
puts("[FAILURE]");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Walk time less than threshold of %lu us\n", FAIL_THRESH);
|
||||||
|
puts("[SUCCESS]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
25
tests/cb_mux_bench/tests/01-run.py
Executable file
25
tests/cb_mux_bench/tests/01-run.py
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2018 Acutam Automation, LLC
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def testfunc(child):
|
||||||
|
child.expect_exact("cb_mux benchmark application")
|
||||||
|
child.expect(u"Populating cb_mux list with \d+ items")
|
||||||
|
child.expect_exact("Finding the last list entry")
|
||||||
|
child.expect(u"List walk time: \d+ us")
|
||||||
|
child.expect(u"Walk time less than threshold of \d+ us")
|
||||||
|
child.expect_exact("[SUCCESS]")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
|
||||||
|
from testrunner import run
|
||||||
|
sys.exit(run(testfunc))
|
||||||
Loading…
x
Reference in New Issue
Block a user