Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: app/tests/port_tests.c

Issue 1478653002: [kernel][port] port group test (Closed) Base URL: https://github.com/travisg/lk.git@master
Patch Set: for review Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 Carlos Pizano-Uribe cpu@chromium.org 2 * Copyright (c) 2015 Carlos Pizano-Uribe cpu@chromium.org
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining 4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files 5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction, 6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge, 7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software, 8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so, 9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions: 10 * subject to the following conditions:
11 * 11 *
12 * The above copyright notice and this permission notice shall be 12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software. 13 * included in all copies or substantial portions of the Software.
14 * 14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 #include <debug.h> 24 #include <debug.h>
25 #include <err.h> 25 #include <err.h>
26 #include <rand.h>
26 #include <string.h> 27 #include <string.h>
27 #include <rand.h> 28 #include <trace.h>
28 29
29 #include <kernel/port.h> 30 #include <kernel/port.h>
30 #include <kernel/thread.h> 31 #include <kernel/thread.h>
31 32
32 #include <platform.h> 33 #include <platform.h>
33 34
35 #define LOCAL_TRACE 0
36
34 void* context1 = (void*) 0x53; 37 void* context1 = (void*) 0x53;
35 38
36 static void dump_port_result(const port_result_t* result) 39 static void dump_port_result(const port_result_t* result)
37 { 40 {
38 const port_packet_t* p = &result->packet; 41 const port_packet_t* p = &result->packet;
39 printf("[%02x %02x %02x %02x %02x %02x %02x %02x]\n", 42 LTRACEF("[%02x %02x %02x %02x %02x %02x %02x %02x]\n",
40 p->value[0], p->value[1], p->value[2], p->value[3], 43 p->value[0], p->value[1], p->value[2], p->value[3],
41 p->value[4], p->value[5], p->value[6], p->value[7]); 44 p->value[4], p->value[5], p->value[6], p->value[7]);
42 } 45 }
43 46
44 static int single_thread_basic(void) 47 static int single_thread_basic(void)
45 { 48 {
46 port_t w_port; 49 port_t w_port;
47 status_t st = port_create("sh_prt1", PORT_MODE_UNICAST, &w_port); 50 status_t st = port_create("sh_prt1", PORT_MODE_UNICAST, &w_port);
48 if (st < 0) { 51 if (st < 0) {
49 printf("could not create port, status = %d\n", st); 52 printf("could not create port, status = %d\n", st);
50 return __LINE__; 53 return __LINE__;
51 } 54 }
52 55
53 port_t r_port; 56 port_t r_port;
54 st = port_open("sh_prt0", context1, &r_port); 57 st = port_open("sh_prt0", context1, &r_port);
55 if (st != ERR_NOT_FOUND) { 58 if (st != ERR_NOT_FOUND) {
56 printf("expected not to find port, status = %d\n", st); 59 printf("expected not to find port, status = %d\n", st);
57 return __LINE__; 60 return __LINE__;
58 } 61 }
59 62
60 st = port_open("sh_prt1", context1, &r_port); 63 st = port_open("sh_prt1", context1, &r_port);
61 if (st < 0) { 64 if (st < 0) {
62 printf("could not open port, status = %d\n", st); 65 printf("could not open port, status = %d\n", st);
63 return __LINE__; 66 return __LINE__;
64 } 67 }
65 68
66
67 port_packet_t packet[3] = { 69 port_packet_t packet[3] = {
68 {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}}, 70 {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}},
69 {{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11}}, 71 {{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11}},
70 {{0x33, 0x66, 0x99, 0xcc, 0x33, 0x66, 0x99, 0xcc}}, 72 {{0x33, 0x66, 0x99, 0xcc, 0x33, 0x66, 0x99, 0xcc}},
71 }; 73 };
72 74
73 st = port_write(w_port, &packet[0], 1); 75 st = port_write(w_port, &packet[0], 1);
74 if (st < 0) { 76 if (st < 0) {
75 printf("could not write port, status = %d\n", st); 77 printf("could not write port, status = %d\n", st);
76 return __LINE__; 78 return __LINE__;
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 if (retcode) 396 if (retcode)
395 goto fail; 397 goto fail;
396 398
397 return 0; 399 return 0;
398 400
399 fail: 401 fail:
400 printf("child thread exited with %d\n", retcode); 402 printf("child thread exited with %d\n", retcode);
401 return __LINE__; 403 return __LINE__;
402 } 404 }
403 405
406 #define CMD_PORT_CTX ((void*) 0x77)
407 #define TS1_PORT_CTX ((void*) 0x11)
408 #define TS2_PORT_CTX ((void*) 0x12)
409
410 typedef enum {
411 ADD_PORT,
412 QUIT
413 } action_t;
414
415 typedef struct {
416 action_t what;
417 port_t port;
418 } watcher_cmd;
419
420 status_t send_watcher_cmd(port_t cmd_port, action_t action, port_t port)
421 {
422 watcher_cmd cmd = {action, port};
423 return port_write(cmd_port, ((port_packet_t*) &cmd), 1);;
424 }
425
426 static int group_watcher_thread(void *arg)
427 {
428 port_t watched[8] = {0};
429 status_t st = port_open("grp_ctrl", CMD_PORT_CTX, &watched[0]);
430 if (st < 0) {
431 printf("could not open port, status = %d\n", st);
432 return __LINE__;
433 }
434
435 size_t count = 1;
436 port_t group;
437 int ctx_count = -1;
438
439 while (true) {
440 st = port_group(watched, count, &group);
441 if (st < 0) {
442 printf("could not make group, status = %d\n", st);
443 return __LINE__;
444 }
445
446 port_result_t pr;
447 while (true) {
448 st = port_read(group, INFINITE_TIME, &pr);
449 if (st < 0) {
450 printf("could not read port, status = %d\n", st);
451 return __LINE__;
452 }
453
454 if (pr.ctx == CMD_PORT_CTX) {
455 break;
456 } else if (pr.ctx == TS1_PORT_CTX) {
457 ctx_count += 1;
458 } else if (pr.ctx == TS2_PORT_CTX) {
459 ctx_count += 2;
460 } else {
461 printf("unknown context %p\n", pr.ctx);
462 return __LINE__;
463 }
464 }
465
466 // Either adding a port or exiting; either way close the
467 // existing group port and create a new one if needed
468 // at the top of the loop.
469
470 port_close(group);
471 watcher_cmd* wc = (watcher_cmd*) &pr.packet;
472
473 if (wc->what == ADD_PORT) {
474 watched[count++] = wc->port;
475 } else if (wc->what == QUIT) {
476 break;
477 } else {
478 printf("unknown command %d\n", wc->what);
479 return __LINE__;
480 }
481 }
482
483 if (ctx_count != 2) {
484 printf("unexpected context count %d", ctx_count);
485 return __LINE__;
486 }
487
488 printf("group watcher shutdown\n");
489
490 for (size_t ix = 0; ix != count; ++ix) {
491 st = port_close(watched[ix]);
492 if (st < 0) {
493 printf("failed to close read port, status = %d\n", st);
494 return __LINE__;
495 }
496 }
497
498 return 0;
499 }
500
501 static status_t make_port_pair(const char* name, void* ctx, port_t* write, port_ t* read)
502 {
503 status_t st = port_create(name, PORT_MODE_UNICAST, write);
504 if (st < 0)
505 return st;
506 return port_open(name,ctx, read);
507 }
508
509 int group_basic(void)
510 {
511 // we spin a thread that connects to a well known port, then we
512 // send two ports that it will add to a group port.
513 port_t cmd_port;
514 status_t st = port_create("grp_ctrl", PORT_MODE_UNICAST, &cmd_port);
515 if (st < 0 ) {
516 printf("could not create port, status = %d\n", st);
517 return __LINE__;
518 }
519
520 thread_t* wt = thread_create(
521 "g_watcher", &group_watcher_thread, NULL, DEFAULT_PRIORIT Y, DEFAULT_STACK_SIZE);
522 thread_resume(wt);
523
524 port_t w_test_port1, r_test_port1;
525 st = make_port_pair("tst_port1", TS1_PORT_CTX, &w_test_port1, &r_test_port1) ;
526 if (st < 0)
527 return __LINE__;
528
529 port_t w_test_port2, r_test_port2;
530 st = make_port_pair("tst_port2", TS2_PORT_CTX, &w_test_port2, &r_test_port2) ;
531 if (st < 0)
532 return __LINE__;
533
534 st = send_watcher_cmd(cmd_port, ADD_PORT, r_test_port1);
535 if (st < 0)
536 return __LINE__;
537
538 st = send_watcher_cmd(cmd_port, ADD_PORT, r_test_port2);
539 if (st < 0)
540 return __LINE__;
541
542 thread_sleep(50);
543
544 port_packet_t pp = {{0}};
545 st = port_write(w_test_port1, &pp, 1);
546 if (st < 0)
547 return __LINE__;
548
549 st = port_write(w_test_port2, &pp, 1);
550 if (st < 0)
551 return __LINE__;
552
553 st = send_watcher_cmd(cmd_port, QUIT, 0);
554 if (st < 0)
555 return __LINE__;
556
557 int retcode = -1;
558 thread_join(wt, &retcode, INFINITE_TIME);
559 if (retcode) {
560 printf("child thread exited with %d\n", retcode);
561 return __LINE__;
562 }
563
564 st = port_close(w_test_port1);
565 if (st < 0)
566 return __LINE__;
567 st = port_close(w_test_port2);
568 if (st < 0)
569 return __LINE__;
570 st = port_close(cmd_port);
571 if (st < 0)
572 return __LINE__;
573 st = port_destroy(w_test_port1);
574 if (st < 0)
575 return __LINE__;
576 st = port_destroy(w_test_port2);
577 if (st < 0)
578 return __LINE__;
579 st = port_destroy(cmd_port);
580 if (st < 0)
581 return __LINE__;
582
583 return 0;
584 }
585
404 #define RUN_TEST(t) result = t(); if (result) goto fail 586 #define RUN_TEST(t) result = t(); if (result) goto fail
405 587
406 int port_tests(void) 588 int port_tests(void)
407 { 589 {
408 int result; 590 int result;
409 int count = 2; 591 int count = 3;
410 while (count--) { 592 while (count--) {
411 RUN_TEST(single_thread_basic); 593 RUN_TEST(single_thread_basic);
412 RUN_TEST(two_threads_basic); 594 RUN_TEST(two_threads_basic);
595 RUN_TEST(group_basic);
413 } 596 }
414 597
415 printf("all tests passed\n"); 598 printf("all tests passed\n");
416 return 0; 599 return 0;
417 fail: 600 fail:
418 printf("test failed at line %d\n", result); 601 printf("test failed at line %d\n", result);
419 return 1; 602 return 1;
420 } 603 }
421 604
422 #undef RUN_TEST 605 #undef RUN_TEST
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698