diff --git a/src/components/implementation/tests/bench_sched_yield/bench_sched_yield.c b/src/components/implementation/tests/bench_sched_yield/bench_sched_yield.c index aba0f30143..8d53abe7ae 100644 --- a/src/components/implementation/tests/bench_sched_yield/bench_sched_yield.c +++ b/src/components/implementation/tests/bench_sched_yield/bench_sched_yield.c @@ -17,36 +17,47 @@ /* lo and hi is actually running at the same prio */ #define ITERATION 10000 -/* #define PRINT_ALL */ +#define PRINT_ALL thdid_t yield_hi = 0, yield_lo = 0; + volatile cycles_t start; -volatile cycles_t end; +volatile int count; struct perfdata perf; cycles_t result[ITERATION] = {0, }; /*** - * We're measuring 2-way context switch time. + * We're measuring one-way context switch time. */ void yield_hi_thd(void *d) { - /* Never stops running; low priority controls how many iters to run. */ - while (1) { + cycles_t end; + + while (count < ITERATION) { debug("h1,"); + + start = time_now(); sched_thd_yield_to(yield_lo); + end = time_now(); + debug("h2,"); + + perfdata_add(&perf, end - start); + + count++; } + + while (1) ; } void yield_lo_thd(void *d) { - int i; - int first = 0; + cycles_t end; - for (i = 0; i < ITERATION + 1; i++) { + while (count < ITERATION) { debug("l1,"); start = time_now(); @@ -55,16 +66,16 @@ yield_lo_thd(void *d) debug("l2,"); - if (first == 0) first = 1; - else perfdata_add(&perf, end - start); + perfdata_add(&perf, end - start); + + count++; } - perfdata_calc(&perf); #ifdef PRINT_ALL - perfdata_all(&perf); -#else - perfdata_print(&perf); + perfdata_raw(&perf); #endif + perfdata_calc(&perf); + perfdata_print(&perf); while (1) ; } @@ -77,6 +88,8 @@ test_yield(void) SCHED_PARAM_CONS(SCHEDP_PRIO, 6) }; + count = 0; + perfdata_init(&perf, "Context switch time", result, ITERATION); printc("Create threads:\n"); diff --git a/src/components/implementation/tests/bench_sl_yield/bench_sl_yield.c b/src/components/implementation/tests/bench_sl_yield/bench_sl_yield.c index 75a27832bc..aa1091a1ea 100644 --- a/src/components/implementation/tests/bench_sl_yield/bench_sl_yield.c +++ b/src/components/implementation/tests/bench_sl_yield/bench_sl_yield.c @@ -19,7 +19,7 @@ /* lo and hi is actually running at the same prio */ #define ITERATION 10000 -/* #define PRINT_ALL */ +#define PRINT_ALL /* Ensure this is the same as what is in sl_mod_fprr.c */ #define SL_FPRR_NPRIOS 32 @@ -32,7 +32,7 @@ struct sl_thd *testing_thread; thdid_t thdid1, thdid2; volatile cycles_t start; -volatile cycles_t end; +volatile int count; struct perfdata perf; cycles_t result[ITERATION] = {0, }; @@ -40,21 +40,32 @@ cycles_t result[ITERATION] = {0, }; static void thd1_fn() { - /* Never stops running; low priority controls how many iters to run. */ - while (1) { + cycles_t end; + + while (count < ITERATION) { debug("h1,"); + + start = time_now(); sl_thd_yield(thdid2); + end = time_now(); + debug("h2,"); + + perfdata_add(&perf, end - start); + + count++; } + + while (1); } static void thd2_fn() { int i; - int first = 0; + cycles_t end; - for (i = 0; i < ITERATION + 1; i++) { + while (count < ITERATION) { debug("l1,"); start = time_now(); @@ -63,16 +74,16 @@ thd2_fn() debug("l2,"); - if (first == 0) first = 1; - else perfdata_add(&perf, end - start); + perfdata_add(&perf, end - start); + + count++; } - perfdata_calc(&perf); #ifdef PRINT_ALL - perfdata_all(&perf); -#else - perfdata_print(&perf); + perfdata_raw(&perf); #endif + perfdata_calc(&perf); + perfdata_print(&perf); while (1) ; } @@ -104,6 +115,8 @@ cos_init(void) struct cos_defcompinfo *defci = cos_defcompinfo_curr_get(); struct cos_compinfo *ci = cos_compinfo_get(defci); + count = 0; + PRINTC("Thread switch benchmark for the scheduling library (sl)\n"); cos_meminfo_init(&(ci->mi), BOOT_MEM_KM_BASE, COS_MEM_KERN_PA_SZ, BOOT_CAPTBL_SELF_UNTYPED_PT); cos_defcompinfo_init(); diff --git a/src/components/implementation/tests/patina_chan_bench/Makefile b/src/components/implementation/tests/patina_chan_bench/Makefile new file mode 100644 index 0000000000..6abccaba96 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_chan_bench/doc.md b/src/components/implementation/tests/patina_chan_bench/doc.md new file mode 100644 index 0000000000..68560c8d20 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench/doc.md @@ -0,0 +1,9 @@ +## tests + +This is the skeleton interface used by the `mkcomponent.sh` script to aid in the creation of a new component. +It provides no functionality, and should never be depended on! +This documentation should be *replaced* in the documentation for a new component. + +### Description + +### Usage and Assumptions diff --git a/src/components/implementation/tests/patina_chan_bench/patina_chan_bench.c b/src/components/implementation/tests/patina_chan_bench/patina_chan_bench.c new file mode 100644 index 0000000000..527902d983 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench/patina_chan_bench.c @@ -0,0 +1,227 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include + +#include +#include + +#define COLD_CACHE +#ifdef COLD_CACHE +#define cache_flush() __cache_flush() +#define COLD_OFFSET 1 +#define COLD_INDEX 0 +#else +#define cache_flush() +#define COLD_OFFSET 0 +#define COLD_INDEX -1 +#endif + +#define CACHE_SIZE 512 * 1024 +#define CACHE_LINE_SIZE 32 + +#undef PATINA_CHAN_TRACE_DEBUG +#ifdef PATINA_CHAN_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* One low-priority thread and one high-priority thread contends on the lock */ +#ifdef COLD_CACHE +#define ITERATION 10 * 10 +#else +#define ITERATION 10 * 1000 +#endif +#undef PRINT_ALL + +/* Two options are available: Sender at low/high prio, data words 4 */ +#define DATA_WORDS 2 + +thdid_t chan_reader = 0, chan_writer = 0; + +typedef unsigned int cycles_32_t; + +volatile cycles_32_t tmp[DATA_WORDS] = { + 0, +}; +volatile cycles_32_t ts1[DATA_WORDS] = { + 0, +}; +volatile cycles_32_t ts2[DATA_WORDS] = { + 0, +}; +volatile cycles_32_t ts3[DATA_WORDS] = { + 0, +}; + +struct perfdata perf1, perf2, perf3; +cycles_t result1[ITERATION] = { + 0, +}; +cycles_t result2[ITERATION] = { + 0, +}; +cycles_t result3[ITERATION] = { + 0, +}; + +patina_chan_t cid; +patina_chan_t cid2; +patina_chan_r_t rid; +patina_chan_r_t rid2; +patina_chan_s_t sid; +patina_chan_s_t sid2; + +volatile char pool[CACHE_SIZE * 4] = { + 0, +}; + +void +__cache_flush() +{ + int agg = 1; + for (int i = 0; i < CACHE_SIZE * 4; i += CACHE_LINE_SIZE) { + pool[i] += agg; + agg = pool[i]; + } +} + +/*** + * The two threads reciprocally sends and receives. + */ +void +chan_reader_thd(void *d) +{ + /* Never stops running; writer controls how many iters to run. */ + while (1) { + debug("r1,"); + patina_channel_recv(rid, tmp, 0, 0); + debug("tsr1: %d,", tmp[0]); + debug("r2,"); + tmp[0] = time_now(); + debug("tsr2: %d,", tmp[0]); + debug("r3,"); + patina_channel_send(sid2, tmp, 0, 0); + debug("r4,"); + } +} + +void +chan_writer_thd(void *d) +{ + int i; + + for (int i = 0; i < ITERATION + COLD_OFFSET; i++) { + debug("w1,"); + cache_flush(); + ts1[0] = time_now(); + debug("ts1: %d,", ts1[0]); + debug("w2,"); + patina_channel_send(sid, ts1, 0, 0); + debug("w3,"); + patina_channel_recv(rid2, ts2, 0, 0); + debug("ts2: %d,", ts2[0]); + debug("w4,"); + ts3[0] = time_now(); + debug("w5,"); + + if (ts2[0] > ts1[0] && ts3[0] > ts2[0] && i != COLD_INDEX) { + perfdata_add(&perf1, ts2[0] - ts1[0]); + perfdata_add(&perf2, ts3[0] - ts2[0]); + perfdata_add(&perf3, ts3[0] - ts1[0]); + } + } + +#ifdef PRINT_ALL + perfdata_raw(&perf1); + perfdata_raw(&perf2); + perfdata_raw(&perf3); +#endif + perfdata_calc(&perf1); + perfdata_calc(&perf2); + perfdata_calc(&perf3); + + perfdata_print(&perf1); + perfdata_print(&perf2); + perfdata_print(&perf3); + + while (1) + ; +} + +void +test_chan(void) +{ + int i; + cycles_t begin, end; + + sched_param_t sps[] = {SCHED_PARAM_CONS(SCHEDP_PRIO, 4), SCHED_PARAM_CONS(SCHEDP_PRIO, 6)}; + + /* Uncontended lock taking/releasing */ + perfdata_init(&perf1, "Uncontended channel - selfloop", result1, ITERATION); + for (i = 0; i < ITERATION; i++) { + begin = time_now(); + + debug("send\n"); + patina_channel_send(sid, tmp, 1, 0); + debug("recv\n"); + patina_channel_recv(rid, tmp, 1, 0); + + end = time_now(); + perfdata_add(&perf1, end - begin); + } +#ifdef PRINT_ALL + perfdata_raw(&perf1); +#endif + perfdata_calc(&perf1); + perfdata_print(&perf1); + + perfdata_init(&perf1, "Contended channel - reader high use this", result1, ITERATION); + perfdata_init(&perf2, "Contended channel - writer high use this", result2, ITERATION); + perfdata_init(&perf3, "Contended channel - roundtrip", result3, ITERATION); + + printc("Create threads:\n"); + + chan_reader = sched_thd_create(chan_reader_thd, NULL); + printc("\tcreating reader thread %d at prio %d\n", chan_reader, sps[1]); + sched_thd_param_set(chan_reader, sps[0]); + + chan_writer = sched_thd_create(chan_writer_thd, NULL); + printc("\tcreating writer thread %d at prio %d\n", chan_writer, sps[0]); + sched_thd_param_set(chan_writer, sps[1]); +} + +void +cos_init(void) +{ + printc("Benchmark for the patina chan (w/sched interface).\n"); +} + +int +main(void) +{ + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000 * 1000)); + + printc("Initializing channel\n"); + + cid = patina_channel_create(sizeof(cycles_32_t), DATA_WORDS, 0, CHAN_DEFAULT); + cid2 = patina_channel_create(sizeof(cycles_32_t), DATA_WORDS, 0, CHAN_DEFAULT); + + printc("Initializing end points\n"); + + sid = patina_channel_get_send(cid); + rid = patina_channel_get_recv(cid); + sid2 = patina_channel_get_send(cid2); + rid2 = patina_channel_get_recv(cid2); + + test_chan(); + + printc("Running benchmark, exiting main thread...\n"); + + return 0; +} diff --git a/src/components/implementation/tests/patina_chan_bench_inter_recv/Makefile b/src/components/implementation/tests/patina_chan_bench_inter_recv/Makefile new file mode 100644 index 0000000000..6abccaba96 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_recv/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_chan_bench_inter_recv/doc.md b/src/components/implementation/tests/patina_chan_bench_inter_recv/doc.md new file mode 100644 index 0000000000..68560c8d20 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_recv/doc.md @@ -0,0 +1,9 @@ +## tests + +This is the skeleton interface used by the `mkcomponent.sh` script to aid in the creation of a new component. +It provides no functionality, and should never be depended on! +This documentation should be *replaced* in the documentation for a new component. + +### Description + +### Usage and Assumptions diff --git a/src/components/implementation/tests/patina_chan_bench_inter_recv/patina_chan_bench_inter_recv.c b/src/components/implementation/tests/patina_chan_bench_inter_recv/patina_chan_bench_inter_recv.c new file mode 100644 index 0000000000..2f291e0269 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_recv/patina_chan_bench_inter_recv.c @@ -0,0 +1,102 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include +#include +#include +#include + +#undef CHAN_TRACE_DEBUG +#ifdef CHAN_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +patina_chan_s_t sid; +patina_chan_r_t rid; +patina_event_t evt; + +/* Keep these settings below consistent with the sender side */ +#undef USE_EVTMGR + +#define TEST_CHAN_ITEM_SZ sizeof(u32_t) +#define TEST_CHAN_NSLOTS 2 +#define TEST_CHAN_SEND_ID 3 +#define TEST_CHAN_RECV_ID 4 +#define TEST_CHAN_PRIO_SELF 4 + +typedef unsigned int cycles_32_t; + +int +main(void) +{ + cycles_t wakeup; + cycles_32_t tmp; +#ifdef USE_EVTMGR + evt_res_id_t evt_id; + evt_res_data_t evtdata; + evt_res_type_t evtsrc; +#endif + + printc("Component chan receiver: executing main.\n"); + + /* See if event manager is in use. If yes, log the receiver channel into it */ +#ifdef USE_EVTMGR + patina_event_create(&evt, 1); + patina_event_add(&evt, rid, 0); + printc("Receiver side event created.\n"); +#endif + + /* + * This sleep in both hi and lo comps lets the benchmark run + * more predictably on HW and on Qemu. + * + * Likely because this helps the priority change in cos_init take effect! + * Or because this lets the initialization of both ends of channels complete before tests start! + */ + wakeup = time_now() + time_usec2cyc(1000 * 1000); + sched_thd_block_timeout(0, wakeup); + + /* Never stops running; sender controls how many iters to run. */ + while (1) { + debug("r1,"); +#ifdef USE_EVTMGR + /* Receive from the events then the channel */ + while (patina_channel_recv(rid, &tmp, 1, CHAN_NONBLOCKING) == CHAN_TRY_AGAIN) + patina_event_wait(&evt, NULL, 0); +#else + patina_channel_recv(rid, &tmp, 1, 0); +#endif + debug("tsr1: %d,", tmp); + debug("r2,"); + tmp = time_now(); + debug("tsr2: %d,", tmp); + debug("r3,"); + patina_channel_send(sid, &tmp, 1, 0); + debug("r4,"); + } +} + + +/* We initialize channel and threads before executing main - here the scheduler doesn't even work so we guarantee good + * init */ +void +cos_init(void) +{ + printc("Component chan receiver initializing:\n\tCreate channel %d\n", TEST_CHAN_SEND_ID); + sid = patina_channel_retrieve_send(TEST_CHAN_ITEM_SZ, TEST_CHAN_NSLOTS, TEST_CHAN_SEND_ID); + + printc("\tCreate channel %d\n", TEST_CHAN_RECV_ID); + rid = patina_channel_retrieve_recv(TEST_CHAN_ITEM_SZ, TEST_CHAN_NSLOTS, TEST_CHAN_RECV_ID); + + printc("\tPriority %d for self!\n", TEST_CHAN_PRIO_SELF); + if (sched_thd_param_set(cos_thdid(), sched_param_pack(SCHEDP_PRIO, TEST_CHAN_PRIO_SELF))) { + printc("sched_thd_param_set failed.\n"); + assert(0); + } +} diff --git a/src/components/implementation/tests/patina_chan_bench_inter_send/Makefile b/src/components/implementation/tests/patina_chan_bench_inter_send/Makefile new file mode 100644 index 0000000000..6abccaba96 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_send/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_chan_bench_inter_send/doc.md b/src/components/implementation/tests/patina_chan_bench_inter_send/doc.md new file mode 100644 index 0000000000..68560c8d20 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_send/doc.md @@ -0,0 +1,9 @@ +## tests + +This is the skeleton interface used by the `mkcomponent.sh` script to aid in the creation of a new component. +It provides no functionality, and should never be depended on! +This documentation should be *replaced* in the documentation for a new component. + +### Description + +### Usage and Assumptions diff --git a/src/components/implementation/tests/patina_chan_bench_inter_send/patina_chan_bench_inter_send.c b/src/components/implementation/tests/patina_chan_bench_inter_send/patina_chan_bench_inter_send.c new file mode 100644 index 0000000000..aff9d84926 --- /dev/null +++ b/src/components/implementation/tests/patina_chan_bench_inter_send/patina_chan_bench_inter_send.c @@ -0,0 +1,141 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include +#include +#include +#include + +#undef CHAN_TRACE_DEBUG +#ifdef CHAN_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +patina_chan_s_t sid; +patina_chan_r_t rid; +patina_event_t evt; + +#define ITERATION 10 * 1000 +#undef USE_EVTMGR +#define PRINT_ALL + +#define TEST_CHAN_ITEM_SZ sizeof(u32_t) +#define TEST_CHAN_NSLOTS 2 +#define TEST_CHAN_SEND_ID 4 +#define TEST_CHAN_RECV_ID 3 +/* We are the sender, and we will be responsible for collecting resulting data */ +#define TEST_CHAN_PRIO_SELF 5 + +typedef unsigned int cycles_32_t; + +struct perfdata perf1, perf2, perf3; +cycles_t result1[ITERATION] = { + 0, +}; +cycles_t result2[ITERATION] = { + 0, +}; +cycles_t result3[ITERATION] = { + 0, +}; + +int +main(void) +{ + int i; + cycles_t wakeup; + cycles_32_t ts1, ts2, ts3; +#ifdef USE_EVTMGR + evt_res_id_t evt_id; + evt_res_data_t evtdata; + evt_res_type_t evtsrc; +#endif + + printc("Component chan sender: executing main.\n"); + + /* Send data to receiver so it can register for channels */ + +#ifdef USE_EVTMGR + patina_event_create(&evt, 1); + patina_event_add(&evt, rid, 0); + printc("Sender side event created.\n"); +#endif + + /* + * This sleep in both hi and lo comps lets the benchmark run + * more predictably on HW and on Qemu. + * + * Likely because this helps the priority change in cos_init take effect! + * Or because this lets the initialization of both ends of channels complete before tests start! + */ + wakeup = time_now() + time_usec2cyc(1000 * 1000); + sched_thd_block_timeout(0, wakeup); + + for (int i = 0; i < ITERATION; i++) { + debug("w1,"); + ts1 = time_now(); + debug("ts1: %d,", ts1); + debug("w2,"); + patina_channel_send(sid, &ts1, 1, 0); + debug("w3,"); +#ifdef USE_EVTMGR + /* Receive from the events then the channel */ + while (patina_channel_recv(rid, &ts2, 1, CHAN_NONBLOCKING) == CHAN_TRY_AGAIN) + patina_event_wait(&evt, NULL, 0); +#else + patina_channel_recv(rid, &ts2, 1, 0); +#endif + debug("ts2: %d,", ts2); + debug("w4,"); + ts3 = time_now(); + debug("w5,"); + + if (ts2 > ts1 && ts3 > ts2) { + perfdata_add(&perf1, ts2 - ts1); + perfdata_add(&perf2, ts3 - ts2); + perfdata_add(&perf3, ts3 - ts1); + } + } + +#ifdef PRINT_ALL + perfdata_raw(&perf1); + perfdata_raw(&perf2); + perfdata_raw(&perf3); +#endif + perfdata_calc(&perf1); + perfdata_calc(&perf2); + perfdata_calc(&perf3); + + perfdata_print(&perf1); + perfdata_print(&perf2); + perfdata_print(&perf3); + + while (1) + ; +} + +void +cos_init(void) +{ + perfdata_init(&perf1, "IPC channel - reader high use this", result1, ITERATION); + perfdata_init(&perf2, "IPC channel - writer high use this", result2, ITERATION); + perfdata_init(&perf3, "IPC channel - roundtrip", result3, ITERATION); + + printc("Component chan sender initializing:\n\tJoin channel %d\n", TEST_CHAN_SEND_ID); + sid = patina_channel_retrieve_send(TEST_CHAN_ITEM_SZ, TEST_CHAN_NSLOTS, TEST_CHAN_SEND_ID); + + printc("\tJoin channel %d\n", TEST_CHAN_RECV_ID); + rid = patina_channel_retrieve_recv(TEST_CHAN_ITEM_SZ, TEST_CHAN_NSLOTS, TEST_CHAN_RECV_ID); + + printc("\tPriority %d for self!\n", TEST_CHAN_PRIO_SELF); + if (sched_thd_param_set(cos_thdid(), sched_param_pack(SCHEDP_PRIO, TEST_CHAN_PRIO_SELF))) { + printc("sched_thd_param_set failed.\n"); + BUG(); + } +} diff --git a/src/components/implementation/tests/patina_event_bench/Makefile b/src/components/implementation/tests/patina_event_bench/Makefile new file mode 100644 index 0000000000..70ed7df4c4 --- /dev/null +++ b/src/components/implementation/tests/patina_event_bench/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_event_bench/patina_event_bench.c b/src/components/implementation/tests/patina_event_bench/patina_event_bench.c new file mode 100644 index 0000000000..391a7c9f4f --- /dev/null +++ b/src/components/implementation/tests/patina_event_bench/patina_event_bench.c @@ -0,0 +1,120 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include + +#include +#include + +#undef EVENT_TRACE_DEBUG +#ifdef EVENT_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +#define ITERATION 10 * 1000 +#define PRINT_ALL + +patina_sem_t sid; +patina_event_t evt; +evt_res_id_t rid; + +thdid_t evt_hi = 0, evt_lo = 0; +volatile int flag = 0; + +volatile cycles_t start; +volatile cycles_t end; + +struct perfdata perf; +cycles_t result[ITERATION] = { + 0, +}; + +void +evt_hi_thd(void *d) +{ + int i; + + for (i = 0; i < ITERATION; i++) { + debug("h1"); + patina_event_wait(&evt, NULL, 0); + end = time_now(); + + debug("h2"); + perfdata_add(&perf, end - start); + + debug("h3"); + patina_sem_give(sid); + } + +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + while (1) + ; +} + +void +evt_lo_thd(void *d) +{ + while (1) { + debug("l1"); + start = time_now(); + patina_event_debug_trigger(rid); + + debug("l2"); + patina_sem_take(sid); + } +} + +void +test_evt(void) +{ + int i; + int first = 0; + cycles_t start, end; + + sched_param_t sps[] = {SCHED_PARAM_CONS(SCHEDP_PRIO, 4), SCHED_PARAM_CONS(SCHEDP_PRIO, 6)}; + + sid = patina_sem_create(0, 0); + patina_event_create(&evt, 1); + rid = patina_event_debug_fake_add(&evt); + + perfdata_init(&perf, "Event latency - total", result, ITERATION); + + printc("Create threads:\n"); + + evt_lo = sched_thd_create(evt_lo_thd, NULL); + printc("\tcreating lo thread %d at prio %d\n", evt_lo, sps[0]); + sched_thd_param_set(evt_lo, sps[1]); + + evt_hi = sched_thd_create(evt_hi_thd, NULL); + printc("\tcreating hi thread %d at prio %d\n", evt_hi, sps[0]); + sched_thd_param_set(evt_hi, sps[0]); +} + +void +cos_init(void) +{ + printc("Benchmark for the event (w/sched interface).\n"); +} + +int +main(void) +{ + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000 * 1000)); + + test_evt(); + + printc("Running benchmark, exiting main thread...\n"); + + return 0; +} diff --git a/src/components/implementation/tests/patina_mutex_bench/Makefile b/src/components/implementation/tests/patina_mutex_bench/Makefile new file mode 100644 index 0000000000..70ed7df4c4 --- /dev/null +++ b/src/components/implementation/tests/patina_mutex_bench/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_mutex_bench/patina_mutex_bench.c b/src/components/implementation/tests/patina_mutex_bench/patina_mutex_bench.c new file mode 100644 index 0000000000..7c362b1337 --- /dev/null +++ b/src/components/implementation/tests/patina_mutex_bench/patina_mutex_bench.c @@ -0,0 +1,184 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include + +#include +#include + +#define COLD_CACHE +#ifdef COLD_CACHE +#define cache_flush() __cache_flush() +#define COLD_OFFSET 1 +#define COLD_INDEX 0 +#else +#define cache_flush() +#define COLD_OFFSET 0 +#define COLD_INDEX -1 +#endif + +#define CACHE_SIZE 512 * 1024 +#define CACHE_LINE_SIZE 32 + +#undef LOCK_TRACE_DEBUG +#ifdef LOCK_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* One low-priority thread and one high-priority thread contends on the lock */ +#ifdef COLD_CACHE +#define ITERATION 10 * 10 +#define SLEEP_TIME 100 * 1000 +#else +#define ITERATION 10 * 1000 +#define SLEEP_TIME 1000 +#endif + +#define PRINT_ALL + +patina_mutex_t mid; +thdid_t lock_hi = 0, lock_lo = 0; +volatile int flag = 0; + +volatile cycles_t start; +volatile cycles_t end; + +struct perfdata perf; +cycles_t result[ITERATION] = { + 0, +}; + +volatile char pool[CACHE_SIZE * 4] = { + 0, +}; + +void +__cache_flush() +{ + int agg = 1; + for (int i = 0; i < CACHE_SIZE * 4; i += CACHE_LINE_SIZE) { + pool[i] += agg; + agg = pool[i]; + } +} + +/*** + * The high priority thread periodically challenges the lock while the low priority thread keeps spinning. + * When the low-priority thread detects that the flag is changed, it knows that the lock is challenged. + * Execution: hi take -> lo release -> hi release, there is 1 contended take, 1 release, and 2 ctxsws. + */ +void +lock_hi_thd(void *d) +{ + /* Never stops running; low priority controls how many iters to run. */ + while (1) { + debug("h1,"); + sched_thd_block(0); + sched_thd_block_timeout(0, time_now() + time_usec2cyc(SLEEP_TIME)); + + debug("h2,"); + cache_flush(); + flag = 1; + start = time_now(); + patina_mutex_lock(mid); + patina_mutex_unlock(mid); + + end = time_now(); + debug("h3,"); + } +} + +void +lock_lo_thd(void *d) +{ + int i; + + for (i = 0; i < ITERATION + COLD_OFFSET; i++) { + debug("l1,"); + sched_thd_wakeup(lock_hi); + + debug("l2,"); + flag = 0; + patina_mutex_lock(mid); + + debug("l3,"); + while (flag != 1) {} + patina_mutex_unlock(mid); + + if (i != COLD_INDEX) { perfdata_add(&perf, end - start); } + debug("l4,"); + } + +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + while (1) + ; +} + +void +test_lock(void) +{ + int i; + + sched_param_t sps[] = {SCHED_PARAM_CONS(SCHEDP_PRIO, 4), SCHED_PARAM_CONS(SCHEDP_PRIO, 6)}; + + mid = patina_mutex_create(0); + + /* Uncontended lock taking/releasing */ + perfdata_init(&perf, "Uncontended lock - take+release", result, ITERATION); + for (i = 0; i < ITERATION + COLD_OFFSET; i++) { + cache_flush(); + start = time_now(); + + patina_mutex_lock(mid); + patina_mutex_unlock(mid); + + end = time_now(); + if (i != COLD_INDEX) { perfdata_add(&perf, end - start); } + } +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + perfdata_init(&perf, "Contended lock - take+release", result, ITERATION); + + printc("Create threads:\n"); + + lock_lo = sched_thd_create(lock_lo_thd, NULL); + printc("\tcreating lo thread %d at prio %d\n", lock_lo, sps[1]); + sched_thd_param_set(lock_lo, sps[1]); + + lock_hi = sched_thd_create(lock_hi_thd, NULL); + printc("\tcreating hi thread %d at prio %d\n", lock_hi, sps[0]); + sched_thd_param_set(lock_hi, sps[0]); +} + +void +cos_init(void) +{ + printc("Benchmark for the crt_lock (w/sched interface).\n"); +} + +int +main(void) +{ + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000 * 1000)); + + test_lock(); + + printc("Running benchmark, exiting main thread...\n"); + + return 0; +} diff --git a/src/components/implementation/tests/patina_sem_bench/Makefile b/src/components/implementation/tests/patina_sem_bench/Makefile new file mode 100644 index 0000000000..70ed7df4c4 --- /dev/null +++ b/src/components/implementation/tests/patina_sem_bench/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_sem_bench/patina_sem_bench.c b/src/components/implementation/tests/patina_sem_bench/patina_sem_bench.c new file mode 100644 index 0000000000..2452f14ca5 --- /dev/null +++ b/src/components/implementation/tests/patina_sem_bench/patina_sem_bench.c @@ -0,0 +1,150 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include + +#include +#include + +#undef SEM_TRACE_DEBUG +#ifdef SEM_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* One low-priority thread and one high-priority thread contends on the semaphore */ +#define ITERATION 10 * 1000 +#define PRINT_ALL + +patina_sem_t sid; +thdid_t sem_hi = 0, sem_lo = 0; +volatile int flag = 0; + +volatile cycles_t start; +volatile cycles_t end; + +struct perfdata perf; +cycles_t result[ITERATION] = { + 0, +}; + +/*** + * The high priority thread periodically challenges the sem while the low priority thread keeps spinning. + * When the low-priority thread detects that the flag is changed, it knows that the sem is challenged. + * Execution: hi take -> lo release -> hi release, there is 1 contended take, 1 give, and 2 ctxsws. + */ +void +sem_hi_thd(void *d) +{ + /* Never stops running; low priority controls how many iters to run. */ + while (1) { + debug("h1"); + sched_thd_block(0); + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000)); + + debug("h2"); + flag = 1; + start = time_now(); + + patina_sem_take(sid); + patina_sem_give(sid); + + end = time_now(); + debug("h3"); + } +} + +void +sem_lo_thd(void *d) +{ + int i; + + for (i = 0; i < ITERATION; i++) { + debug("l1"); + sched_thd_wakeup(sem_hi); + + debug("l2"); + flag = 0; + patina_sem_take(sid); + + debug("l3"); + while (flag != 1) {} + + patina_sem_give(sid); + + perfdata_add(&perf, end - start); + debug("l4"); + } + +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + while (1) + ; +} + +void +test_sem(void) +{ + int i; + cycles_t start, end; + + sched_param_t sps[] = {SCHED_PARAM_CONS(SCHEDP_PRIO, 4), SCHED_PARAM_CONS(SCHEDP_PRIO, 6)}; + + sid = patina_sem_create(1, 0); + + /* Uncontended semaphore taking/releasing */ + perfdata_init(&perf, "Uncontended semaphore - take+give", result, ITERATION); + for (i = 0; i < ITERATION; i++) { + start = time_now(); + + patina_sem_take(sid); + patina_sem_give(sid); + + end = time_now(); + perfdata_add(&perf, end - start); + } +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + perfdata_init(&perf, "Contended semaphore - take+give", result, ITERATION); + + printc("Create threads:\n"); + + sem_lo = sched_thd_create(sem_lo_thd, NULL); + printc("\tcreating lo thread %d at prio %d\n", sem_lo, sps[1]); + sched_thd_param_set(sem_lo, sps[1]); + + sem_hi = sched_thd_create(sem_hi_thd, NULL); + printc("\tcreating hi thread %d at prio %d\n", sem_hi, sps[0]); + sched_thd_param_set(sem_hi, sps[0]); +} + +void +cos_init(void) +{ + printc("Benchmark for the crt_sem (w/sched interface).\n"); +} + +int +main(void) +{ + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000 * 1000)); + + test_sem(); + + printc("Running benchmark, exiting main thread...\n"); + + return 0; +} diff --git a/src/components/implementation/tests/patina_timer_bench/Makefile b/src/components/implementation/tests/patina_timer_bench/Makefile new file mode 100644 index 0000000000..70ed7df4c4 --- /dev/null +++ b/src/components/implementation/tests/patina_timer_bench/Makefile @@ -0,0 +1,18 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The set of interfaces that this component exports for use by other +# components. This is a list of the interface names. +INTERFACE_EXPORTS = +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component patina ubench +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +include Makefile.subsubdir diff --git a/src/components/implementation/tests/patina_timer_bench/patina_timer_bench.c b/src/components/implementation/tests/patina_timer_bench/patina_timer_bench.c new file mode 100644 index 0000000000..65948b5e3f --- /dev/null +++ b/src/components/implementation/tests/patina_timer_bench/patina_timer_bench.c @@ -0,0 +1,170 @@ +/* + * Copyright 2020, Bite Ye, Runyu Pan and Gabriel Parmer, GWU, gparmer@gwu.edu. + * + * This uses a two clause BSD License. + */ + +#include +#include + +#include +#include + +#define COLD_CACHE +#ifdef COLD_CACHE +#define cache_flush() __cache_flush() +#define COLD_OFFSET 1 +#define COLD_INDEX 0 +#else +#define cache_flush() +#define COLD_OFFSET 0 +#define COLD_INDEX -1 +#endif + +#define CACHE_SIZE 512 * 1024 +#define CACHE_LINE_SIZE 32 + +#undef TMR_TRACE_DEBUG +#ifdef TMR_TRACE_DEBUG +#define debug(format, ...) printc(format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* High-priority thread interrupts the low-priority thread by timer ticks */ +#ifdef COLD_OFFSET +#define ITERATION 10 * 10 +#define TMR_PERIODIC_TIME 1000 * 1000 +#else +#define ITERATION 10 * 1000 +#define TMR_PERIODIC_TIME 10 * 1000 +#endif + +#define DROP_THRESHOLD 0x1000000U + +#define PRINT_ALL + +thdid_t tmr_hi = 0, tmr_lo = 0; + +typedef unsigned int cycles_32_t; +volatile cycles_32_t start; +volatile cycles_32_t end; + +struct perfdata perf; +cycles_t result[ITERATION] = { + 0, +}; + +volatile char pool[CACHE_SIZE * 4] = { + 0, +}; + +void +__cache_flush() +{ + int agg = 1; + for (int i = 0; i < CACHE_SIZE * 4; i += CACHE_LINE_SIZE) { + pool[i] += agg; + agg = pool[i]; + } +} + +/*** + * The high priority thread sets up a periodic timer while the low priority thread keeps looping and updating + * the timing value variable. The variable is a 32-bit one so that it can be updated atomically. We always + * drop values larger than DROP_THRESHOLD (clearly impossible; appears due to counter overflow). + */ +void +tmr_hi_thd(void *d) +{ + int i; + patina_time_t t; + patina_timer_t tid; + patina_event_t evt; + + printc("Call into timer manager to make a timer.\n"); + tid = patina_timer_create(); + + printc("Call into event manager to make a event.\n"); + patina_event_create(&evt, 1); + + /* + * Add the timer event to the event set, the associate the timer with that event ID so + * the timer manager knows which event to trigger when the timer expires. + */ + patina_event_add(&evt, tid, 0); + + /* Start the timer */ + patina_time_create(&t, 0, TMR_PERIODIC_TIME); + patina_timer_periodic(tid, NULL, &t); + + /* Event loop */ + i = 0; + while (i < ITERATION + COLD_OFFSET) { + cache_flush(); + patina_event_wait(&evt, NULL, 0); + end = (cycles_32_t)time_now(); + + if ((end - start) > DROP_THRESHOLD) continue; + + if (i != COLD_INDEX) { perfdata_add(&perf, end - start); } + debug("%lld.\n", end - start); + + i++; + } + +#ifdef PRINT_ALL + perfdata_raw(&perf); +#endif + perfdata_calc(&perf); + perfdata_print(&perf); + + while (1) + ; +} + +void +tmr_lo_thd(void *d) +{ + /* Runs indefinitely */ + while (1) { start = (cycles_32_t)time_now(); } +} + +void +test_tmr(void) +{ + int i; + + sched_param_t sps[] = {SCHED_PARAM_CONS(SCHEDP_PRIO, 4), SCHED_PARAM_CONS(SCHEDP_PRIO, 6)}; + + + perfdata_init(&perf, "Timer latency - total", result, ITERATION); + + printc("Create threads:\n"); + + tmr_lo = sched_thd_create(tmr_lo_thd, NULL); + printc("\tcreating lo thread %d at prio %d\n", tmr_lo, sps[1]); + sched_thd_param_set(tmr_lo, sps[1]); + + tmr_hi = sched_thd_create(tmr_hi_thd, NULL); + printc("\tcreating hi thread %d at prio %d\n", tmr_hi, sps[0]); + sched_thd_param_set(tmr_hi, sps[0]); +} + +void +cos_init(void) +{ + printc("Benchmark for the tmrmgr (w/sched & evt interface).\n"); +} + +int +main(void) +{ + sched_thd_block_timeout(0, time_now() + time_usec2cyc(1000 * 1000)); + + test_tmr(); + + printc("Running benchmark, exiting main thread...\n"); + + return 0; +} diff --git a/src/components/implementation/tests/test.c b/src/components/implementation/tests/test.c new file mode 100644 index 0000000000..33b130abcc --- /dev/null +++ b/src/components/implementation/tests/test.c @@ -0,0 +1,8 @@ +#include + +int main() +{ + void *p = 0; + printf("%p %p\n", p, p + 1); + return 0; +} diff --git a/src/components/implementation/tests/unit_pingpong/Makefile b/src/components/implementation/tests/unit_pingpong/Makefile index 6a48f05d9d..403512929a 100644 --- a/src/components/implementation/tests/unit_pingpong/Makefile +++ b/src/components/implementation/tests/unit_pingpong/Makefile @@ -9,7 +9,7 @@ INTERFACE_EXPORTS = INTERFACE_DEPENDENCIES = init pong # The library dependencies this component is reliant on for # compilation/linking (this is a list of directory names in lib/) -LIBRARY_DEPENDENCIES = kernel ps +LIBRARY_DEPENDENCIES = kernel ps ubench # Note: Both the interface and library dependencies should be # *minimal*. That is to say that removing a dependency should cause # the build to fail. The build system does not validate this diff --git a/src/components/implementation/tests/unit_pingpong/ping.c b/src/components/implementation/tests/unit_pingpong/ping.c index c5e24908cb..c3fa43181b 100644 --- a/src/components/implementation/tests/unit_pingpong/ping.c +++ b/src/components/implementation/tests/unit_pingpong/ping.c @@ -1,12 +1,18 @@ #include #include +#include #include #include -#define ITER 1024 +#define ITER 10 * 1000 +#define PRINT_ALL volatile ps_tsc_t fast_path, all_args; +struct perfdata perf1, perf2; +ps_tsc_t result1[ITER] = {0, }; +ps_tsc_t result2[ITER] = {0, }; + void cos_init(void) { @@ -23,6 +29,7 @@ cos_init(void) printc("Ping component %ld: cos_init execution\n", cos_compid()); + pong_call(); ret = pong_ret(); assert(ret == 42); @@ -48,19 +55,27 @@ cos_init(void) tid = pong_ids(&us, &them); assert(cos_thdid() == tid && us != them && us == cos_compid()); - begin = ps_tsc(); + perfdata_init(&perf1, "Ping-pong - fast_path", result1, ITER); + for (i = 0; i < ITER; i++) { + begin = ps_tsc(); pong_call(); + end = ps_tsc(); + + perfdata_add(&perf1, end - begin); } - end = ps_tsc(); - fast_path = (end - begin)/ITER; - begin = ps_tsc(); + + perfdata_init(&perf2, "Ping-pong - three_return", result2, ITER); + for (i = 0; i < ITER; i++) { + begin = ps_tsc(); pong_argsrets(0, 0, 0, 0, &r0, &r1); + end = ps_tsc(); + + perfdata_add(&perf2, end - begin); } - end = ps_tsc(); - all_args = (end - begin)/ITER; + return; } @@ -68,9 +83,19 @@ cos_init(void) int main(void) { - printc("Ping component %ld: main execution\n", cos_compid()); - printc("Fast-path invocation: %llu cycles\n", fast_path); - printc("Three return value invocation: %llu cycles\n", all_args); +#ifdef PRINT_ALL + perfdata_raw(&perf1); +#endif + perfdata_calc(&perf1); + perfdata_print(&perf1); + +#ifdef PRINT_ALL + perfdata_raw(&perf2); +#endif + perfdata_calc(&perf2); + perfdata_print(&perf2); + + while(1); return 0; } diff --git a/src/components/lib/patina/Makefile b/src/components/lib/patina/Makefile new file mode 100644 index 0000000000..297100059c --- /dev/null +++ b/src/components/lib/patina/Makefile @@ -0,0 +1,63 @@ +# Required variables used to drive the compilation process. It is OK +# for many of these to be empty. +# +# The library names associated with .a files output that are linked +# (via, for example, -lpatina) into dependents. This list should be +# "patina" for output files such as libpatina.a. +LIBRARY_OUTPUT = patina +# The .o files that are mandatorily linked into dependents. This is +# rarely used, and only when normal .a linking rules will avoid +# linking some necessary objects. This list is of names (for example, +# patina) which will generate patina.lib.o. Do NOT include the list of .o +# files here. Please note that using this list is *very rare* and +# should only be used when the .a support above is not appropriate. +OBJECT_OUTPUT = +# The path within this directory that holds the .h files for +# dependents to compile with (./ by default). Will be fed into the -I +# compiler arguments. +INCLUDE_PATHS = . +# The interfaces this component is dependent on for compilation (this +# is a list of directory names in interface/) +INTERFACE_DEPENDENCIES = evt +# The library dependencies this component is reliant on for +# compilation/linking (this is a list of directory names in lib/) +LIBRARY_DEPENDENCIES = component crt util chan tmr sl +# Note: Both the interface and library dependencies should be +# *minimal*. That is to say that removing a dependency should cause +# the build to fail. The build system does not validate this +# minimality; that's on you! + +# There are two different *types* of Makefiles for libraries. +# 1. Those that are Composite-specific, and simply need an easy way to +# compile and itegrate their code. +# 2. Those that aim to integrate external libraries into +# Composite. These focus on "driving" the build process of the +# external library, then pulling out the resulting files and +# directories. These need to be flexible as all libraries are +# different. + +# Type 1, Composite library: This is the default Makefile for +# libraries written for composite. Get rid of this if you require a +# custom Makefile (e.g. if you use an existing +# (non-composite-specific) library. An example of this is `kernel`. +include Makefile.lib + +## Type 2, external library: If you need to specialize the Makefile +## for an external library, you can add the external code as a +## subdirectory, and drive its compilation, and integration with the +## system using a specialized Makefile. The Makefile must generate +## lib$(LIBRARY_OUTPUT).a and $(OBJECT_OUTPUT).lib.o, and have all of +## the necessary include paths in $(INCLUDE_PATHS). +## +## To access the Composite Makefile definitions, use the following. An +## example of a Makefile written in this way is in `ps/`. +# +# include Makefile.src Makefile.comp Makefile.dependencies +# .PHONY: all clean init distclean +## Fill these out with your implementation +# all: +# clean: +# +## Default rules: +# init: clean all +# distclean: clean diff --git a/src/components/lib/patina/doc.md b/src/components/lib/patina/doc.md new file mode 100644 index 0000000000..922f4810fe --- /dev/null +++ b/src/components/lib/patina/doc.md @@ -0,0 +1,9 @@ +## patina + +This is the skeleton library used by the `mklib.sh` script to aid in the creation of a new library. +It provides no functionality, and should never be depended on! +This documentation should be *replaced* in the documentation for a new library. + +### Description + +### Usage and Assumptions diff --git a/src/components/lib/patina/patina.h b/src/components/lib/patina/patina.h new file mode 100644 index 0000000000..9312578ada --- /dev/null +++ b/src/components/lib/patina/patina.h @@ -0,0 +1,10 @@ +#ifndef PATINA_H +#define PATINA_H + +#include +#include +#include +#include +#include + +#endif diff --git a/src/components/lib/patina/patina_chan.c b/src/components/lib/patina/patina_chan.c new file mode 100644 index 0000000000..9e2558060f --- /dev/null +++ b/src/components/lib/patina/patina_chan.c @@ -0,0 +1,250 @@ +/** + * Redistribution of this file is permitted under the BSD two clause license. + * + * Copyright 2020, The George Washington University + * Author: Bite Ye, bitye@gwu.edu + */ + +#include +#include +#include +#include +#include + +/** + * This is a wrapper of patina's native channel library. + * For detail API usage guide, please check source codes + * under 'src/components/lib/chan' + */ + +SS_STATIC_SLAB(chan, struct chan, PATINA_MAX_NUM_CHAN); +SS_STATIC_SLAB(chan_rcv, struct chan_rcv, PATINA_MAX_NUM_CHAN); +SS_STATIC_SLAB(chan_snd, struct chan_snd, PATINA_MAX_NUM_CHAN); + +/** + * Create a channel + * + * Currently we only support CHAN_DEFAULT as flag, hence + * the arugment 'flags' has no effect + * Also note that name as arugment is not supported. + * + * Arguments: + * - @type_size: size of the item in this channel + * - @queue_length: size of this channel + * - @ch_name: no effect + * - @falgs: no effect + * + * @return: id of the channel just been created. + */ +patina_chan_t +patina_channel_create(size_t type_size, size_t queue_length, int ch_name, size_t flags) +{ + assert(type_size & queue_length); + + struct chan *c = ss_chan_alloc(); + assert(c); + + assert(chan_init(c, type_size, queue_length, CHAN_DEFAULT)); + + ss_chan_activate(c); + + return (patina_chan_t)c | PATINA_T_CHAN; +} + +/** + * Get recv endpoint of a channel + * + * Arguments: + * - @cid: channel id + * + * @return: id of the recv endpoint + */ +patina_chan_r_t +patina_channel_get_recv(patina_chan_t cid) +{ + assert(cid); + + struct chan * c = (struct chan *)(cid & PATINA_T_MASK); + struct chan_rcv *r = ss_chan_rcv_alloc(); + assert(r); + + assert(!chan_rcv_init(r, c)); + + ss_chan_rcv_activate(r); + + return (patina_chan_r_t)r | PATINA_T_CHAN_R; +} + +/** + * Get send endpoint + * + * Arugments: + * - @cid: channel id + * + * @return: id of the send endpoint + */ +patina_chan_s_t +patina_channel_get_send(patina_chan_t cid) +{ + assert(cid); + + struct chan * c = (struct chan *)(cid & PATINA_T_MASK); + struct chan_snd *s = ss_chan_snd_alloc(); + assert(s); + + assert(!chan_snd_init(s, c)); + + ss_chan_snd_activate(s); + + return (patina_chan_s_t)s | PATINA_T_CHAN_S; +} + +/** + * Get recv endpoint using ch_name (which currently being allocated while booting, + * see chanmgr for more detail). + * + * Arguments: + * - @type_size: size of the item in this channel + * - @queue_length: size of the channel + * - @ch_name: id of the channel + * + * @return: id of the recv endpoint + */ +patina_chan_r_t +patina_channel_retrieve_recv(size_t type_size, size_t queue_length, int ch_name) +{ + assert(type_size & queue_length); + + struct chan_rcv *r = ss_chan_rcv_alloc(); + assert(r); + + assert(!chan_rcv_init_with(r, ch_name, type_size, queue_length, CHAN_DEFAULT)); + + ss_chan_rcv_activate(r); + + return (patina_chan_s_t)r | PATINA_T_CHAN_R; +} + +/** + * Get send endpoint using ch_name (which currently being allocated while booting, + * see chanmgr for more detail). + * + * Arguments: + * - @type_size: size of the item in this channel + * - @queue_length: size of the channel + * - @ch_name: id of the channel + * + * @return: id of the send endpoint + */ +patina_chan_s_t +patina_channel_retrieve_send(size_t type_size, size_t queue_length, int ch_name) +{ + assert(type_size & queue_length); + + struct chan_snd *s = ss_chan_snd_alloc(); + assert(s); + + assert(!chan_snd_init_with(s, ch_name, type_size, queue_length, CHAN_DEFAULT)); + + ss_chan_snd_activate(s); + + return (patina_chan_s_t)s | PATINA_T_CHAN_S; +} + +/** + * Close a channel (this func close channel endpoint) + * + * Arguments: + * - @eid: id of the endpoint + * + * @return: always success (return 0). + */ +int +patina_channel_close(size_t eid) +{ + assert(eid); + + if ((eid & (~PATINA_T_MASK)) == PATINA_T_CHAN_R) { + struct chan_rcv *r = (struct chan_rcv *)(eid & PATINA_T_MASK); + + chan_rcv_teardown(r); + ss_chan_rcv_free(r); + } else if ((eid & (~PATINA_T_MASK)) == PATINA_T_CHAN_S) { + struct chan_snd *s = (struct chan_snd *)(eid & PATINA_T_MASK); + + chan_snd_teardown(s); + ss_chan_snd_free(s); + } + + return 0; +} + +/** + * Close a channel (close THE channel) + * + * Arguments: + * - @cid: id of the channel + * + * @return: always return 0 + */ +int +patina_channel_destroy(patina_chan_t cid) +{ + assert(cid); + + struct chan *c = (struct chan *)(cid & PATINA_T_MASK); + + chan_teardown(c); + ss_chan_free(c); + + return 0; +} + +/** + * Send data through channel + * + * For the flags, currently we don't do any translate so please use native chan lib's + * flags. + * + * Arguments: + * - @scid: id of send endpoint + * - @len: no effect + * - @flags: native chan lib's flags + * + * @return: return 'chan_send's return + */ +patina_channel_send(patina_chan_s_t scid, void *data, size_t len, size_t flags) +{ + assert(scid & data & len); + + return chan_send((struct chan_snd *)(scid & PATINA_T_MASK), data, (chan_flags_t)flags); +} + +/** + * Receive data through channel + * + * For the flags, currently we don't do any translate so please use native chan lib's + * flags. + * + * Arguments: + * - @scid: id of recv endpoint + * - @len: no effect + * - @flags: native chan lib's flags + * + * @return: return 'chan_recv's return + */ +int +patina_channel_recv(patina_chan_r_t rcid, void *buf, size_t len, size_t flags) +{ + assert(rcid & buf & len); + + return chan_recv((struct chan_rcv *)(rcid & PATINA_T_MASK), buf, (chan_flags_t)flags); +} + +/* NOT IMPLEMENTED */ +int +patina_channel_get_status(size_t cid, struct patina_channel_status *status) +{ + assert(0); + return 0; +} diff --git a/src/components/lib/patina/patina_chan.h b/src/components/lib/patina/patina_chan.h new file mode 100644 index 0000000000..3dc0dac6d2 --- /dev/null +++ b/src/components/lib/patina/patina_chan.h @@ -0,0 +1,26 @@ +#ifndef PATINA_CHAN_H +#define PATINA_CHAN_H + +#include +#include + +#define PATINA_MAX_NUM_CHAN 32 + +typedef size_t patina_chan_t; +typedef size_t patina_chan_s_t; +typedef size_t patina_chan_r_t; + +struct patina_channel_status; + +patina_chan_t patina_channel_create(size_t type_size, size_t queue_length, int ch_name, size_t flags); +patina_chan_r_t patina_channel_get_recv(patina_chan_t cid); +patina_chan_s_t patina_channel_get_send(patina_chan_t cid); +patina_chan_r_t patina_channel_retrieve_recv(size_t type_size, size_t queue_length, int ch_name); +patina_chan_s_t patina_channel_retrieve_send(size_t type_size, size_t queue_length, int ch_name); +int patina_channel_close(size_t cid); +int patina_channel_destroy(patina_chan_t cid); +int patina_channel_send(patina_chan_s_t scid, void *data, size_t len, size_t flags); +int patina_channel_recv(patina_chan_r_t rcid, void *buf, size_t len, size_t flags); +int patina_channel_get_status(size_t cid, struct patina_channel_status *status); + +#endif diff --git a/src/components/lib/patina/patina_evt.c b/src/components/lib/patina/patina_evt.c new file mode 100644 index 0000000000..cf83e41b6c --- /dev/null +++ b/src/components/lib/patina/patina_evt.c @@ -0,0 +1,200 @@ +/** + * Redistribution of this file is permitted under the BSD two clause license. + * + * Copyright 2020, The George Washington University + * Author: Bite Ye, bitye@gwu.edu + */ + +#include +#include +#include +#include +#include + +/** + * This is a wrapper of patina's native evt interface. + * For detail API usage guide, please check source codes + * under 'src/components/interface/evt.h' + */ + +/** + * Create a event + * + * Arguments: + * - @eid: id of the event (a struct, see 'patina_evt.h') + * - @n_sources: number of sources can be hold in this event + * + * @return: id of the event + */ +int +patina_event_create(patina_event_t *eid, uint32_t n_sources) +{ + assert(eid & n_sources); + + return evt_init((struct evt *)eid, n_sources); +} + + +/** + * Add a source to a event + * + * Currently we don't support any flags + * + * Arguments: + * - @eid: id of the event + * - @src: id of the source + * - @flags: no effect + * + * @return: always return 0 for timer and return corresponding native APIs' returns for others + */ +int +patina_event_add(patina_event_t *eid, size_t src, size_t flags) +{ + assert(eid & src); + + evt_res_id_t id; + + if (!eid || !src) { return -1; } + + id = evt_add((struct evt *)eid, 0, 0); + assert(id); + + if ((src & (~PATINA_T_MASK)) == PATINA_T_TIMER) { + ((struct patina_tmr *)(src & PATINA_T_MASK))->eid = eid; + return 0; + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN) { + return chan_evt_associate((struct chan *)(src & PATINA_T_MASK), id); + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN_R) { + return chan_rcv_evt_associate((struct chan_rcv *)(src & PATINA_T_MASK), id); + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN_S) { + return chan_snd_evt_associate((struct chan_snd *)(src & PATINA_T_MASK), id); + } + + assert(0); +} + +/** + * Remove a source from a event + * + * Arguments: + * - @eid: id of the event + * - @src: id of the source + * - @flags: no effect + * + * @return: return native APIs' returns + */ +int +patina_event_remove(patina_event_t *eid, size_t src, size_t flags) +{ + assert(eid & src); + + evt_res_id_t id = 0; + + if (!eid || !src) { return -1; } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_TIMER) { + id = tmr_evt_associated((struct tmr *)(src & PATINA_T_MASK)); + tmr_evt_disassociate((struct tmr *)(src & PATINA_T_MASK)); + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN) { + id = chan_evt_associated((struct chan *)(src & PATINA_T_MASK)); + chan_evt_disassociate((struct chan *)(src & PATINA_T_MASK)); + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN_R) { + id = chan_rcv_evt_associated((struct chan_rcv *)(src & PATINA_T_MASK)); + chan_rcv_evt_disassociate((struct chan_rcv *)(src & PATINA_T_MASK)); + } + + if ((src & (~PATINA_T_MASK)) == PATINA_T_CHAN_S) { + id = chan_snd_evt_associated((struct chan_snd *)(src & PATINA_T_MASK)); + chan_snd_evt_disassociate((struct chan_snd *)(src & PATINA_T_MASK)); + } + + return evt_rem((struct evt *)eid, id); +} + +/** + * Delete a event + * + * Arguments: + * - @eid: id of the event + * + * @return: return 'evt_teardown's return + */ +int +patina_event_delete(patina_event_t *eid) +{ + assert(eid); + + return evt_teardown((struct evt *)eid); +} + +/** + * Wait on a event (blocking) + * + * Arguments: + * - @eid: id of the event + * - @events: holder of event info (an array, allow batching) + * - @num: number of events client wants + * + * @return: return 'evt_get's return + */ +int +patina_event_wait(patina_event_t *eid, struct patina_event_info events[], size_t num) +{ + assert(eid & events & num); + + word_t tmp; + + return evt_get((struct evt *)eid, EVT_WAIT_DEFAULT, &tmp, &tmp); +} + +/** + * Check on a event (non-blocking) + * + * Arguments: + * - @eid: id of the event + * - @events: holder of event info (an array, allow batching) + * - @num: number of events client wants + * + * @return: return 'evt_get's return + */ +int +patina_event_check(patina_event_t *eid, struct patina_event_info events[], size_t num) +{ + assert(eid & events & num); + + word_t tmp; + + return evt_get((struct evt *)eid, EVT_WAIT_NONBLOCKING, &tmp, &tmp); +} + +/** + * DEBUG usage + */ +evt_res_id_t +patina_event_debug_fake_add(patina_event_t *eid) +{ + assert(eid); + + return evt_add((struct evt *)eid, 0, 0); +} + +/** + * DEBUG usage + */ +int +patina_event_debug_trigger(evt_res_id_t rid) +{ + assert(rid); + + return evt_trigger(rid); +} diff --git a/src/components/lib/patina/patina_evt.h b/src/components/lib/patina/patina_evt.h new file mode 100644 index 0000000000..4179720afa --- /dev/null +++ b/src/components/lib/patina/patina_evt.h @@ -0,0 +1,28 @@ +#ifndef PATINA_EVT_H +#define PATINA_EVT_H + +#include +#include +#include +#include + +#define PATINA_MAX_NUM_EVT 32 + +typedef struct evt patina_event_t; + +struct patina_event_info { + size_t event_src_id; + size_t event_type; +}; + +int patina_event_create(patina_event_t *eid, uint32_t n_sources); +int patina_event_add(patina_event_t *eid, size_t src, size_t flags); +int patina_event_remove(patina_event_t *eid, size_t src, size_t flags); +int patina_event_delete(patina_event_t *eid); +int patina_event_wait(patina_event_t *eid, struct patina_event_info events[], size_t num); +int patina_event_check(patina_event_t *eid, struct patina_event_info events[], size_t num); + +evt_res_id_t patina_event_debug_fake_add(patina_event_t *eid); +int patina_event_debug_trigger(evt_res_id_t rid); + +#endif diff --git a/src/components/lib/patina/patina_mutex.c b/src/components/lib/patina/patina_mutex.c new file mode 100644 index 0000000000..82b1c9a862 --- /dev/null +++ b/src/components/lib/patina/patina_mutex.c @@ -0,0 +1,124 @@ +/** + * Redistribution of this file is permitted under the BSD two clause license. + * + * Copyright 2020, The George Washington University + * Author: Bite Ye, bitye@gwu.edu + */ + +#include +#include +#include +#include + +/** + * This is a wrapper of patina's native crt lib. + * For detail API usage guide, please check source codes + * under 'src/components/lib/crt/' + */ + +SS_STATIC_SLAB(lock, struct crt_lock, PATINA_MAX_NUM_MUTEX); + +/** + * Create a mutex + * Currently we don't support any flags + * + * Arguments: + * - @flags: no effect + * + * @return: id of the mutex + */ +patina_mutex_t +patina_mutex_create(size_t flags) +{ + struct crt_lock *l = ss_lock_alloc(); + if (!l) { return -1; } + + assert(!crt_lock_init(l)) + + ss_lock_activate(l); + + patina_mutex_t mid = (patina_mutex_t)l | PATINA_T_MUTEX; + + return mid; +} + +/** + * Lock a mutex (blocking) + * + * Arugments: + * - @mid: id of the mutex + * + * @return: always success + */ +int +patina_mutex_lock(patina_mutex_t mid) +{ + assert(mid); + + struct crt_lock *l = (struct crt_lock *)(mid & PATINA_T_MASK); + + crt_lock_take(l); + + return 0; +} + +/** + * Try to lock a mutex (non-blocking) + * + * Arugments: + * - @mid: id of the mutex + * + * @return: always success + */ +int +patina_mutex_try_lock(patina_mutex_t mid) +{ + assert(mid); + + struct crt_lock *l = (struct crt_lock *)(mid & PATINA_T_MASK); + + crt_lock_try_take(l); + + return 0; +} + +/** + * Unlock a mutex + * + * Arugments: + * - @mid: id of the mutex + * + * @return: always success + */ +int +patina_mutex_unlock(patina_mutex_t mid) +{ + assert(mid); + + struct crt_lock *l = (struct crt_lock *)(mid & PATINA_T_MASK); + + crt_lock_release(l); + + return 0; +} + +/** + * Destroy a mutex + * + * Arugments: + * - @mid: id of the mutex + * + * @return: always success + */ +int +patina_mutex_destroy(patina_mutex_t mid) +{ + assert(mid); + + struct crt_lock *l = (struct crt_lock *)(mid & PATINA_T_MASK); + + crt_lock_teardown(l); + ss_lock_free(l); + + return 0; +} diff --git a/src/components/lib/patina/patina_mutex.h b/src/components/lib/patina/patina_mutex.h new file mode 100644 index 0000000000..6e7a9f02a4 --- /dev/null +++ b/src/components/lib/patina/patina_mutex.h @@ -0,0 +1,17 @@ +#ifndef PATINA_MUTEX_H +#define PATINA_MUTEX_H + +#include +#include + +#define PATINA_MAX_NUM_MUTEX 32 + +typedef size_t patina_mutex_t; + +patina_mutex_t patina_mutex_create(size_t flags); +int patina_mutex_lock(patina_mutex_t mid); +int patina_mutex_try_lock(patina_mutex_t mid); +int patina_mutex_unlock(patina_mutex_t mid); +int patina_mutex_destroy(patina_mutex_t mid); + +#endif diff --git a/src/components/lib/patina/patina_sem.c b/src/components/lib/patina/patina_sem.c new file mode 100644 index 0000000000..84f9b054b1 --- /dev/null +++ b/src/components/lib/patina/patina_sem.c @@ -0,0 +1,127 @@ +/** + * Redistribution of this file is permitted under the BSD two clause license. + * + * Copyright 2020, The George Washington University + * Author: Bite Ye, bitye@gwu.edu + */ + +#include +#include +#include +#include + +/** + * This is a wrapper of patina's native crt lib. + * For detail API usage guide, please check source codes + * under 'src/components/lib/crt/' + */ + +SS_STATIC_SLAB(sem, struct crt_sem, PATINA_MAX_NUM_SEM); + +/** + * Create a semaphore + * Currently we don't support any flags + * + * Arguments: + * - @init_value: inital value + * - @flags: no effect + * + * @return: id of the semaphore + */ +patina_sem_t +patina_sem_create(size_t init_value, size_t flags) +{ + assert(init_value); + + struct crt_sem *s = ss_sem_alloc(); + if (!s) { return -1; } + + assert(!crt_sem_init(s, (unsigned long)init_value)) + + ss_sem_activate(s); + + patina_sem_t sid = (patina_sem_t)s | PATINA_T_SEM; + + return sid; +} + +/** + * Take a sempahore (blocking) + * + * Arugments: + * - @mid: id of the semaphore + * + * @return: always success + */ +int +patina_sem_take(patina_sem_t sid) +{ + assert(sid); + + struct crt_sem *s = (struct crt_sem *)(sid & PATINA_T_MASK); + + crt_sem_take(s); + + return 0; +} + +/** + * Try to take a sempahore (non-blocking) + * + * Arugments: + * - @mid: id of the semaphore + * + * @return: always success + */ +int +patina_sem_try_take(patina_sem_t sid) +{ + assert(sid); + + struct crt_sem *s = (struct crt_sem *)(sid & PATINA_T_MASK); + + crt_sem_try_take(s); + + return 0; +} + +/** + * Give a sempahore + * + * Arugments: + * - @mid: id of the semaphore + * + * @return: always success + */ +int +patina_sem_give(patina_sem_t sid) +{ + assert(sid); + + struct crt_sem *s = (struct crt_sem *)(sid & PATINA_T_MASK); + + crt_sem_give(s); + + return 0; +} + +/** + * Destroy a sempahore + * + * Arugments: + * - @mid: id of the semaphore + * + * @return: always success + */ +int +patina_sem_destroy(patina_sem_t sid) +{ + assert(sid); + + struct crt_sem *s = (struct crt_sem *)(sid & PATINA_T_MASK); + + crt_sem_teardown(s); + ss_sem_free(s); + + return 0; +} diff --git a/src/components/lib/patina/patina_sem.h b/src/components/lib/patina/patina_sem.h new file mode 100644 index 0000000000..720fb48aae --- /dev/null +++ b/src/components/lib/patina/patina_sem.h @@ -0,0 +1,17 @@ +#ifndef PATINA_SEM_H +#define PATINA_SEM_H + +#include +#include + +#define PATINA_MAX_NUM_SEM 32 + +typedef size_t patina_sem_t; + +patina_sem_t patina_sem_create(size_t init_value, size_t flags); +int patina_sem_take(patina_sem_t sid); +int patina_sem_try_take(patina_sem_t sid); +int patina_sem_give(patina_sem_t sid); +int patina_sem_destroy(patina_sem_t sid); + +#endif diff --git a/src/components/lib/patina/patina_timer.c b/src/components/lib/patina/patina_timer.c new file mode 100644 index 0000000000..39223178fd --- /dev/null +++ b/src/components/lib/patina/patina_timer.c @@ -0,0 +1,207 @@ +/** + * Redistribution of this file is permitted under the BSD two clause license. + * + * Copyright 2020, The George Washington University + * Author: Bite Ye, bitye@gwu.edu + */ + +#include +#include +#include +#include +#include + +/** + * This is a wrapper of patina's native tmr lib. + * For detail API usage guide, please check source codes + * under 'src/components/lib/tmr/' + */ + +SS_STATIC_SLAB(patina_tmr, struct patina_tmr, PATINA_MAX_NUM_TIMER); + +/** + * Get current time (in sec + usec format) + * + * Arguments: + * - @result: time struct (see 'patina_timer.h') + * + * @return: void + */ +void +patina_time_current(struct time *result) +{ + assert(result); + + u64_t time_now = time_now_usec(); + + result->sec = time_now / (1000 * 1000); + result->usec = time_now % (1000 * 1000); + + return; +} + +/** + * Create a time struct + * + * Arguments: + * - @a: time struct + * - @sec: seconds + * - @usec: micro seconds + * + * @return: void + */ +void +patina_time_create(struct time *a, u64_t sec, u32_t usec) +{ + assert(a); + + a->sec = sec; + a->usec = usec; +} + +/** + * Add some time to a time struct + * + * Arguments: + * - @a: the target time struct + * - @b: how many time client wants to add + * + * @return: always success + */ +int +patina_time_add(struct time *a, struct time *b) +{ + assert(a & b); + assert(!(a->sec + b->sec < a->sec || a->usec + b->usec < a->usec)) + + a->sec = a->sec + b->sec; + a->usec = a->usec + b->usec; + + return 0; +} + +/** + * Subtract some time from a time struct + * + * Arguments: + * - @a: the target time struct + * - @b: how many time client wants to subtract + * + * @return: always success + */ +int +patina_time_sub(struct time *a, struct time *b) +{ + assert(a & b); + assert(!(a->sec - b->sec > a->sec || a->usec - b->usec > a->usec)) + + a->sec = a->sec - b->sec; + a->usec = a->usec - b->usec; + + return 0; +} + +/* CURRENTLY NOT SUPORTTED! */ +u32_t +patina_timer_precision() +{ + assert(0); + + return 0; +} + +/** + * Create a timer + * + * @return: return id of the timer + */ +patina_timer_t +patina_timer_create() +{ + struct patina_tmr *t = ss_patina_tmr_alloc(); + assert(t); + + t->eid = NULL; + + patina_timer_t tid = (patina_timer_t)t | PATINA_T_TIMER; + + return tid; +} + +/** + * Start a timer (one-shot) + * + * Arguments: + * - @tid: id of the timer + * - @time: delay time + * + * @return: always success + */ +int +patina_timer_start(patina_timer_t tid, struct time *time) +{ + assert(tid & time); + struct patina_tmr *t = (struct patina_tmr *)(tid & PATINA_T_MASK); + + assert(!tmr_init(&t->tmr, (time->sec * 1000 * 1000) + time->usec - time_now_usec(), TMR_ONESHOT)); + + if (t->eid) { + evt_res_id_t id = evt_add((struct evt *)t->eid, 0, 0); + tmr_evt_associate(&t->tmr, id); + } + + assert(!tmr_start(&t->tmr)); + + return 0; +} + +/** + * Start a timer (periodic) + * + * Arguments: + * - @tid: id of the timer + * - @offset: offset time to the first trigger + * - @period: period of the timer + * + * @return: always success + */ +int +patina_timer_periodic(patina_timer_t tid, struct time *offset, struct time *period) +{ + struct patina_tmr *t = (struct patina_tmr *)(tid & PATINA_T_MASK); + + assert(!tmr_init(&t->tmr, (period->sec * 1000 * 1000) + period->usec, TMR_PERIODIC)); + + if (t->eid) { + evt_res_id_t id = evt_add((struct evt *)t->eid, 0, 0); + tmr_evt_associate(&t->tmr, id); + } + + assert(!tmr_start(&t->tmr)); + + return 0; +} + + +/** + * Cancel a timer + * + * Arguments: + * - @tid: id of the timer + * + * @return: return 'tmr_stop's return + */ +int +patina_timer_cancel(patina_timer_t tid) +{ + return tmr_stop(&(((struct patina_tmr *)(tid & PATINA_T_MASK))->tmr)); +} + +/* CURRENTLY NOT SUPPORTED! */ +int +patina_timer_free(patina_timer_t tid) +{ + assert(0); + + return 0; +} diff --git a/src/components/lib/patina/patina_timer.h b/src/components/lib/patina/patina_timer.h new file mode 100644 index 0000000000..ee2db42471 --- /dev/null +++ b/src/components/lib/patina/patina_timer.h @@ -0,0 +1,37 @@ +#ifndef PATINA_TIMER_H +#define PATINA_TIMER_H + +#include +#include +#include + +#define PATINA_MAX_NUM_TIMER 32 + +typedef size_t patina_timer_t; + +struct patina_tmr { + struct tmr tmr; + patina_event_t *eid; +}; + +/** + * Time struct + * hold time in sec + usec format + */ +typedef struct time { + u64_t sec; + u32_t usec; +} patina_time_t; + +void patina_time_current(struct time *result); +void patina_time_create(struct time *a, u64_t sec, u32_t usec); +int patina_time_add(struct time *a, struct time *b); +int patina_time_sub(struct time *a, struct time *b); +u32_t patina_timer_precision(); +patina_timer_t patina_timer_create(); +int patina_timer_start(patina_timer_t tid, struct time *time); +int patina_timer_periodic(patina_timer_t tid, struct time *offset, struct time *period); +int patina_timer_cancel(patina_timer_t tid); +int patina_timer_free(patina_timer_t tid); + +#endif diff --git a/src/components/lib/patina/patina_types.h b/src/components/lib/patina/patina_types.h new file mode 100644 index 0000000000..0a82732a7e --- /dev/null +++ b/src/components/lib/patina/patina_types.h @@ -0,0 +1,17 @@ +#ifndef PATINA_TYPES_H +#define PATINA_TYPES_H + +#define PATINA_T_MASK 0xFFFFFFFC + +typedef enum +{ + PATINA_T_MUTEX = 0, + PATINA_T_SEM = 0, + PATINA_T_TIMER = 0, + PATINA_T_CHAN = 1, + PATINA_T_CHAN_R = 2, + PATINA_T_CHAN_S = 3, + PATINA_T_EVENT = 0, +} patina_types_t; + +#endif diff --git a/src/components/lib/ubench/perfdata.h b/src/components/lib/ubench/perfdata.h index 73936a84d5..4c1d633c37 100644 --- a/src/components/lib/ubench/perfdata.h +++ b/src/components/lib/ubench/perfdata.h @@ -229,7 +229,7 @@ perfdata_99ptile(struct perfdata *pd) static void perfdata_print(struct perfdata *pd) { - printc("PD:%s -sz:%d,SD:%llu,Mean:%llu,99%%:%llu, Max: %llu\n", + printc("#PD:%s -sz:%d,SD:%llu,Mean:%llu,99%%:%llu, Max: %llu\n", pd->name, pd->sz, pd->sd, pd->avg, pd->ptiles[PTILE_99], pd->max); } @@ -240,12 +240,26 @@ perfdata_all(struct perfdata *pd) perfdata_print(pd); - printc(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); + printc("#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); printc("#Latency\n"); for (i = 0 ; i < pd->sz ; i++) printc("V: %llu\n", pd->values[i]); - printc("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); + printc("#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); +} + +static void +perfdata_raw(struct perfdata *pd) +{ + int i; + + printc("#PD:%s\n", pd->name); + printc("#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); + + printc("#Latency\n"); + for (i = 0 ; i < pd->sz ; i++) printc("V: %llu\n", pd->values[i]); + + printc("#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } #endif /* PERFDATA_H */ diff --git a/src/composer/patina_chan_bench.toml b/src/composer/patina_chan_bench.toml new file mode 100644 index 0000000000..d8465ec3c0 --- /dev/null +++ b/src/composer/patina_chan_bench.toml @@ -0,0 +1,52 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "tests" +img = "tests.patina_chan_bench" +implements = [{interface = "init"}] +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" diff --git a/src/composer/patina_chan_bench_inter.toml b/src/composer/patina_chan_bench_inter.toml new file mode 100644 index 0000000000..8a6037c160 --- /dev/null +++ b/src/composer/patina_chan_bench_inter.toml @@ -0,0 +1,58 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "chan_snd" +img = "tests.patina_chan_bench_inter_send" +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" + +[[components]] +name = "chan_rcv" +img = "tests.patina_chan_bench_inter_recv" +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" diff --git a/src/composer/patina_event_bench.toml b/src/composer/patina_event_bench.toml new file mode 100644 index 0000000000..dbb73615b9 --- /dev/null +++ b/src/composer/patina_event_bench.toml @@ -0,0 +1,52 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "tests" +img = "tests.patina_event_bench" +implements = [{interface = "init"}] +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" diff --git a/src/composer/patina_mutex_bench.toml b/src/composer/patina_mutex_bench.toml new file mode 100644 index 0000000000..d1748b1e68 --- /dev/null +++ b/src/composer/patina_mutex_bench.toml @@ -0,0 +1,52 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "tests" +img = "tests.patina_mutex_bench" +implements = [{interface = "init"}] +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" diff --git a/src/composer/patina_sem_bench.toml b/src/composer/patina_sem_bench.toml new file mode 100644 index 0000000000..e234496179 --- /dev/null +++ b/src/composer/patina_sem_bench.toml @@ -0,0 +1,52 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "tests" +img = "tests.patina_sem_bench" +implements = [{interface = "init"}] +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter" diff --git a/src/composer/patina_timer_bench.toml b/src/composer/patina_timer_bench.toml new file mode 100644 index 0000000000..096098214b --- /dev/null +++ b/src/composer/patina_timer_bench.toml @@ -0,0 +1,52 @@ +[system] +description = "Simplest system with crt tests." + +[[components]] +name = "booter" +img = "no_interface.llbooter" +implements = [{interface = "init"}, {interface = "addr"}] +deps = [{srv = "kernel", interface = "init", variant = "kernel"}] +constructor = "kernel" + +[[components]] +name = "capmgr" +img = "capmgr.simple" +deps = [{srv = "booter", interface = "init"}, {srv = "booter", interface = "addr"}] +implements = [{interface = "capmgr"}, {interface = "init"}, {interface = "memmgr"}, {interface = "capmgr_create"}] +constructor = "booter" + +[[components]] +name = "sched" +img = "sched.root_fprr" +deps = [{srv = "capmgr", interface = "init"}, {srv = "capmgr", interface = "capmgr"}, {srv = "capmgr", interface = "memmgr"}] +implements = [{interface = "sched"}, {interface = "init"}] +constructor = "booter" + +[[components]] +name = "chanmgr" +img = "chanmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "capmgr", interface = "capmgr"}] +implements = [{interface = "chanmgr"}, {interface = "chanmgr_evt"}] +constructor = "booter" + +[[components]] +name = "evtmgr" +img = "evt.evtmgr" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}] +implements = [{interface = "evt"}] +constructor = "booter" + +[[components]] +name = "tmrmgr" +img = "tmrmgr.simple" +deps = [{srv = "sched", interface = "init"}, {srv = "sched", interface = "sched"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "evtmgr", interface = "evt"}] +implements = [{interface = "tmrmgr"}] +constructor = "booter" + +[[components]] +name = "tests" +img = "tests.patina_timer_bench" +implements = [{interface = "init"}] +deps = [{srv = "sched", interface = "sched"}, {srv = "sched", interface = "init"}, {srv = "capmgr", interface = "capmgr_create"}, {srv = "capmgr", interface = "memmgr"}, {srv = "evtmgr", interface = "evt"}, {srv = "tmrmgr", interface = "tmrmgr"}, {srv = "chanmgr", interface = "chanmgr"}, {srv = "chanmgr", interface = "chanmgr_evt"}] +baseaddr = "0x1600000" +constructor = "booter"