1#include <barrelfish/barrelfish.h>
2#include <barrelfish/spawn_client.h>
3#include <barrelfish/deferred.h>
4#include <stdio.h>
5#include <string.h>
6
7static int execute_program(coreid_t coreid, int argc, char *argv[],
8                           domainid_t *retdomainid)
9{
10    errval_t err;
11
12    // if the name contains a directory separator, assume it is relative to PWD
13    char *prog = argv[0];
14    assert(retdomainid != NULL);
15
16    argv[argc] = NULL;
17    err = spawn_program(coreid, prog, argv, NULL, SPAWN_FLAGS_NEW_DOMAIN,
18                        retdomainid);
19
20    if (prog != argv[0]) {
21        free(prog);
22    }
23
24    if (err_is_fail(err)) {
25        printf("%s: error spawning: %s\n", argv[0], err_getstring(err));
26        DEBUG_ERR(err, "Spawning Error\n");
27        return -1;
28    }
29
30    return 0;
31}
32
33static uint8_t wait_domain_id(domainid_t domainid)
34{
35    uint8_t exitcode;
36    errval_t err = spawn_wait(domainid, &exitcode, false);
37    if(err_is_fail(err)) {
38        USER_PANIC_ERR(err, "spawn_wait");
39    }
40    return exitcode;
41}
42
43static struct deferred_event myevent;
44static coreid_t loopy_core = 3;
45static coreid_t core_inc = 1;
46static coreid_t next_core = 0;
47#define ROUNDS 2
48static int rounds = 0;
49
50static const int wait_usec = 5e6;
51
52static void restart_core(void *arg)
53{
54    char corestr[3] = { 0 };
55    snprintf(corestr, 2, "%x", next_core);
56    next_core += core_inc;
57    if (next_core > loopy_core) {
58        next_core = core_inc;
59        rounds++;
60    }
61    if (rounds > ROUNDS) {
62        exit(0);
63    }
64
65    // restart a core
66    char *argv[] = {
67        "corectrl",
68        "update",
69        corestr,
70    };
71    domainid_t x86id;
72    debug_printf("restarting core %d\n", next_core);
73    execute_program(disp_get_core_id(), 3, argv, &x86id);
74    wait_domain_id(x86id);
75
76    // wait a bit
77    deferred_event_register(&myevent, get_default_waitset(),
78            wait_usec, MKCLOSURE(restart_core, NULL));
79}
80int main(int argc, char *argv[])
81{
82    if (argc == 3) {
83        loopy_core = atoi(argv[1]);
84        core_inc = atoi(argv[2]);
85    }
86    next_core = core_inc;
87    deferred_event_init(&myevent);
88    // spawn loopy on fixed core
89    char *loopy_argv[1] = { "loopy" };
90    domainid_t retid;
91    execute_program(loopy_core, 1, loopy_argv, &retid);
92
93    // 2: wait a bit
94    deferred_event_register(&myevent, get_default_waitset(),
95            wait_usec, MKCLOSURE(restart_core, NULL));
96
97    while(true) {
98        event_dispatch(get_default_waitset());
99    }
100    return 0;
101}
102