| Index: app/tests/port_tests.c
|
| diff --git a/app/tests/port_tests.c b/app/tests/port_tests.c
|
| index 447c5d236e70e447c645aff2e9b4630c97ea9580..591096c714f8daecb82ad649e7cc8cfca579628e 100644
|
| --- a/app/tests/port_tests.c
|
| +++ b/app/tests/port_tests.c
|
| @@ -23,22 +23,25 @@
|
|
|
| #include <debug.h>
|
| #include <err.h>
|
| -#include <string.h>
|
| #include <rand.h>
|
| +#include <string.h>
|
| +#include <trace.h>
|
|
|
| #include <kernel/port.h>
|
| #include <kernel/thread.h>
|
|
|
| #include <platform.h>
|
|
|
| +#define LOCAL_TRACE 0
|
| +
|
| void* context1 = (void*) 0x53;
|
|
|
| static void dump_port_result(const port_result_t* result)
|
| {
|
| const port_packet_t* p = &result->packet;
|
| - printf("[%02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
| - p->value[0], p->value[1], p->value[2], p->value[3],
|
| - p->value[4], p->value[5], p->value[6], p->value[7]);
|
| + LTRACEF("[%02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
| + p->value[0], p->value[1], p->value[2], p->value[3],
|
| + p->value[4], p->value[5], p->value[6], p->value[7]);
|
| }
|
|
|
| static int single_thread_basic(void)
|
| @@ -63,7 +66,6 @@ static int single_thread_basic(void)
|
| return __LINE__;
|
| }
|
|
|
| -
|
| port_packet_t packet[3] = {
|
| {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}},
|
| {{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11}},
|
| @@ -401,15 +403,196 @@ fail:
|
| return __LINE__;
|
| }
|
|
|
| +#define CMD_PORT_CTX ((void*) 0x77)
|
| +#define TS1_PORT_CTX ((void*) 0x11)
|
| +#define TS2_PORT_CTX ((void*) 0x12)
|
| +
|
| +typedef enum {
|
| + ADD_PORT,
|
| + QUIT
|
| +} action_t;
|
| +
|
| +typedef struct {
|
| + action_t what;
|
| + port_t port;
|
| +} watcher_cmd;
|
| +
|
| +status_t send_watcher_cmd(port_t cmd_port, action_t action, port_t port)
|
| +{
|
| + watcher_cmd cmd = {action, port};
|
| + return port_write(cmd_port, ((port_packet_t*) &cmd), 1);;
|
| +}
|
| +
|
| +static int group_watcher_thread(void *arg)
|
| +{
|
| + port_t watched[8] = {0};
|
| + status_t st = port_open("grp_ctrl", CMD_PORT_CTX, &watched[0]);
|
| + if (st < 0) {
|
| + printf("could not open port, status = %d\n", st);
|
| + return __LINE__;
|
| + }
|
| +
|
| + size_t count = 1;
|
| + port_t group;
|
| + int ctx_count = -1;
|
| +
|
| + while (true) {
|
| + st = port_group(watched, count, &group);
|
| + if (st < 0) {
|
| + printf("could not make group, status = %d\n", st);
|
| + return __LINE__;
|
| + }
|
| +
|
| + port_result_t pr;
|
| + while (true) {
|
| + st = port_read(group, INFINITE_TIME, &pr);
|
| + if (st < 0) {
|
| + printf("could not read port, status = %d\n", st);
|
| + return __LINE__;
|
| + }
|
| +
|
| + if (pr.ctx == CMD_PORT_CTX) {
|
| + break;
|
| + } else if (pr.ctx == TS1_PORT_CTX) {
|
| + ctx_count += 1;
|
| + } else if (pr.ctx == TS2_PORT_CTX) {
|
| + ctx_count += 2;
|
| + } else {
|
| + printf("unknown context %p\n", pr.ctx);
|
| + return __LINE__;
|
| + }
|
| + }
|
| +
|
| + // Either adding a port or exiting; either way close the
|
| + // existing group port and create a new one if needed
|
| + // at the top of the loop.
|
| +
|
| + port_close(group);
|
| + watcher_cmd* wc = (watcher_cmd*) &pr.packet;
|
| +
|
| + if (wc->what == ADD_PORT) {
|
| + watched[count++] = wc->port;
|
| + } else if (wc->what == QUIT) {
|
| + break;
|
| + } else {
|
| + printf("unknown command %d\n", wc->what);
|
| + return __LINE__;
|
| + }
|
| + }
|
| +
|
| + if (ctx_count != 2) {
|
| + printf("unexpected context count %d", ctx_count);
|
| + return __LINE__;
|
| + }
|
| +
|
| + printf("group watcher shutdown\n");
|
| +
|
| + for (size_t ix = 0; ix != count; ++ix) {
|
| + st = port_close(watched[ix]);
|
| + if (st < 0) {
|
| + printf("failed to close read port, status = %d\n", st);
|
| + return __LINE__;
|
| + }
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +static status_t make_port_pair(const char* name, void* ctx, port_t* write, port_t* read)
|
| +{
|
| + status_t st = port_create(name, PORT_MODE_UNICAST, write);
|
| + if (st < 0)
|
| + return st;
|
| + return port_open(name,ctx, read);
|
| +}
|
| +
|
| +int group_basic(void)
|
| +{
|
| + // we spin a thread that connects to a well known port, then we
|
| + // send two ports that it will add to a group port.
|
| + port_t cmd_port;
|
| + status_t st = port_create("grp_ctrl", PORT_MODE_UNICAST, &cmd_port);
|
| + if (st < 0 ) {
|
| + printf("could not create port, status = %d\n", st);
|
| + return __LINE__;
|
| + }
|
| +
|
| + thread_t* wt = thread_create(
|
| + "g_watcher", &group_watcher_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
|
| + thread_resume(wt);
|
| +
|
| + port_t w_test_port1, r_test_port1;
|
| + st = make_port_pair("tst_port1", TS1_PORT_CTX, &w_test_port1, &r_test_port1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + port_t w_test_port2, r_test_port2;
|
| + st = make_port_pair("tst_port2", TS2_PORT_CTX, &w_test_port2, &r_test_port2);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + st = send_watcher_cmd(cmd_port, ADD_PORT, r_test_port1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + st = send_watcher_cmd(cmd_port, ADD_PORT, r_test_port2);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + thread_sleep(50);
|
| +
|
| + port_packet_t pp = {{0}};
|
| + st = port_write(w_test_port1, &pp, 1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + st = port_write(w_test_port2, &pp, 1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + st = send_watcher_cmd(cmd_port, QUIT, 0);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + int retcode = -1;
|
| + thread_join(wt, &retcode, INFINITE_TIME);
|
| + if (retcode) {
|
| + printf("child thread exited with %d\n", retcode);
|
| + return __LINE__;
|
| + }
|
| +
|
| + st = port_close(w_test_port1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| + st = port_close(w_test_port2);
|
| + if (st < 0)
|
| + return __LINE__;
|
| + st = port_close(cmd_port);
|
| + if (st < 0)
|
| + return __LINE__;
|
| + st = port_destroy(w_test_port1);
|
| + if (st < 0)
|
| + return __LINE__;
|
| + st = port_destroy(w_test_port2);
|
| + if (st < 0)
|
| + return __LINE__;
|
| + st = port_destroy(cmd_port);
|
| + if (st < 0)
|
| + return __LINE__;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| #define RUN_TEST(t) result = t(); if (result) goto fail
|
|
|
| int port_tests(void)
|
| {
|
| int result;
|
| - int count = 2;
|
| + int count = 3;
|
| while (count--) {
|
| RUN_TEST(single_thread_basic);
|
| RUN_TEST(two_threads_basic);
|
| + RUN_TEST(group_basic);
|
| }
|
|
|
| printf("all tests passed\n");
|
|
|