#include #include #include "ckb_syscalls.h" #include "spawn_utils.h" const uint64_t SYSCALL_CYCLES_BASE = 500; const uint64_t SPAWN_EXTRA_CYCLES_BASE = 100000; const uint64_t SPAWN_SPAWN_YIELD_CYCLES_BASE = 800; int tic() { static uint64_t tic = 0; uint64_t cur_cycles = ckb_current_cycles(); uint64_t toc = cur_cycles - tic; tic = cur_cycles; return toc; } uint64_t cal_cycles(uint64_t nbase, uint64_t yield, uint64_t extra) { uint64_t r = 0; r += SYSCALL_CYCLES_BASE * nbase; r += SPAWN_SPAWN_YIELD_CYCLES_BASE * yield; r += SPAWN_EXTRA_CYCLES_BASE * extra; return r; } uint64_t cal_cycles_floor(uint64_t nbase, uint64_t yield, uint64_t extra) { return cal_cycles(nbase, yield, extra); } uint64_t cal_cycles_upper(uint64_t nbase, uint64_t yield, uint64_t extra) { return cal_cycles(nbase, yield, extra) + 8192; } int main() { int err = 0; int toc = 0; uint64_t cid = ckb_process_id(); uint64_t pid[5] = {0}; uint64_t fds[5][2][3] = {0}; uint64_t buf[256] = {0}; uint64_t len = 0; switch (cid) { case 0: const char* argv[1] = {0}; for (int i = 1; i < 5; i++) { toc = tic(); err = ckb_pipe(buf); CHECK(err); toc = tic(); CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); fds[i][0][0] = buf[0]; fds[i][1][1] = buf[1]; toc = tic(); err = ckb_pipe(buf); CHECK(err); toc = tic(); CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); fds[i][0][1] = buf[1]; fds[i][1][0] = buf[0]; } // Living Process: 0 // Living Process: 0, 1 // Living Process: 0, 1, 2 // Living Process: 0, 1, 2, 3 // Living Process: 1, 2, 3, 4 // Living Process: 0, 2, 3, 4 for (int i = 1; i < 5; i++) { toc = tic(); spawn_args_t spgs = {.argc = 0, .argv = argv, .process_id = &pid[i], .inherited_fds = fds[i][1]}; err = ckb_spawn(0, CKB_SOURCE_CELL_DEP, 0, 0, &spgs); CHECK(err); toc = tic(); if (i < 4) { CHECK2(toc > cal_cycles_floor(1, 1, 1), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 1), ErrorCommon); } else { CHECK2(toc > cal_cycles_floor(1, 1, 4), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 4), ErrorCommon); } } // Living Process: 0, 2, 3, 4 // Living Process: 0, 1, 3, 4 // Living Process: 0, 2, 3, 4 for (int i = 1; i < 5; i++) { len = 12; toc = tic(); err = ckb_write(fds[i][0][1], "Hello World!", &len); toc = tic(); CHECK(err); if (i < 3) { CHECK2(toc > cal_cycles_floor(1, 1, 2), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 2), ErrorCommon); } else { CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); } err = ckb_close(fds[i][0][1]); CHECK(err); toc = tic(); CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); } // Living Process: 0, 2, 3, 4 // Living Process: 0, 1, 3, 4 // Living Process: 0, 2, 3, 4 // Living Process: 0, 3, 4 // Living Process: 0, 4 // Living Process: 0 for (int i = 1; i < 5; i++) { len = 1024; toc = tic(); err = ckb_read_all(fds[i][0][0], buf, &len); CHECK(err); toc = tic(); if (i == 1) { CHECK2(toc > cal_cycles_floor(1, 1, 2), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 2), ErrorCommon); } if (i == 2) { CHECK2(toc > cal_cycles_floor(1, 1, 1), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 1), ErrorCommon); } if (i >= 3) { CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); } CHECK2(len == 12, ErrorCommon); err = memcmp("Hello World!", buf, len); CHECK(err); } for (int i = 1; i < 5; i++) { int8_t exit_code = 255; toc = tic(); err = ckb_wait(pid[i], &exit_code); CHECK(err); toc = tic(); CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); CHECK(exit_code); } break; case 1: case 2: case 3: case 4: len = 2; toc = tic(); err = ckb_inherited_fds(fds[cid][1], &len); CHECK(err); toc = tic(); CHECK2(toc > cal_cycles_floor(1, 1, 0), ErrorCommon); CHECK2(toc < cal_cycles_upper(1, 1, 0), ErrorCommon); CHECK2(len == 2, ErrorCommon); len = 1024; err = ckb_read_all(fds[cid][1][0], buf, &len); CHECK(err); CHECK2(len == 12, ErrorCommon); err = memcmp("Hello World!", buf, len); CHECK(err); err = ckb_write(fds[cid][1][1], buf, &len); CHECK(err); err = ckb_close(fds[cid][1][1]); CHECK(err); break; } exit: return err; }