156055Srwatson#include <barrelfish/barrelfish.h>
274191Srwatson#include <barrelfish/spawn_client.h>
356055Srwatson#include <barrelfish/deferred.h>
456055Srwatson#include <stdio.h>
556055Srwatson#include <string.h>
656055Srwatson
756055Srwatsonstatic int execute_program(coreid_t coreid, int argc, char *argv[],
856055Srwatson                           struct capref *retdomainid)
956055Srwatson{
1056055Srwatson    errval_t err;
1156055Srwatson
1256055Srwatson    // if the name contains a directory separator, assume it is relative to PWD
1356055Srwatson    char *prog = argv[0];
1456055Srwatson    assert(retdomainid != NULL);
1556055Srwatson
1656055Srwatson    argv[argc] = NULL;
1756055Srwatson    err = spawn_program(coreid, prog, argv, NULL, SPAWN_FLAGS_NEW_DOMAIN,
1856055Srwatson                        retdomainid);
1956055Srwatson
2056055Srwatson    if (prog != argv[0]) {
2156055Srwatson        free(prog);
2256055Srwatson    }
2356055Srwatson
2456055Srwatson    if (err_is_fail(err)) {
2556055Srwatson        printf("%s: error spawning: %s\n", argv[0], err_getstring(err));
2656055Srwatson        DEBUG_ERR(err, "Spawning Error\n");
2766259Srwatson        return -1;
2856055Srwatson    }
2956055Srwatson
3092986Sobrien    return 0;
3192986Sobrien}
3292986Sobrien
3356055Srwatsonstatic uint8_t wait_domain_id(struct capref domainid)
3475185Stmm{
3556055Srwatson    uint8_t exitcode;
3675185Stmm    errval_t err = spawn_wait(domainid, &exitcode, false);
3756055Srwatson    if(err_is_fail(err)) {
38167006Skientzle        USER_PANIC_ERR(err, "spawn_wait");
39167006Skientzle    }
4056055Srwatson    return exitcode;
4156055Srwatson}
4256055Srwatson
43194955Straszstatic struct deferred_event myevent;
4456055Srwatsonstatic coreid_t loopy_core = 3;
4556055Srwatsonstatic coreid_t core_inc = 1;
4656055Srwatsonstatic coreid_t next_core = 0;
4791032Sjedgar#define ROUNDS 2
4891032Sjedgarstatic int rounds = 0;
49194955Strasz
50194955Straszstatic const int wait_usec = 5e6;
5156055Srwatson
5291032Sjedgarstatic void restart_core(void *arg)
5356055Srwatson{
5456055Srwatson    char corestr[3] = { 0 };
5556055Srwatson    snprintf(corestr, 2, "%x", next_core);
5656055Srwatson    next_core += core_inc;
5756055Srwatson    if (next_core > loopy_core) {
5856055Srwatson        next_core = core_inc;
5956055Srwatson        rounds++;
6056055Srwatson    }
6156055Srwatson    if (rounds > ROUNDS) {
6256055Srwatson        exit(0);
6356055Srwatson    }
6456055Srwatson
6556055Srwatson    // restart a core
6656055Srwatson    char *argv[] = {
6756055Srwatson        "corectrl",
6856055Srwatson        "update",
6956055Srwatson        corestr,
7056055Srwatson    };
7156055Srwatson    struct capref x86id;
7256055Srwatson    debug_printf("restarting core %d\n", next_core);
7356055Srwatson    execute_program(disp_get_core_id(), 3, argv, &x86id);
7456055Srwatson    wait_domain_id(x86id);
7556055Srwatson
7656055Srwatson    // wait a bit
7756055Srwatson    deferred_event_register(&myevent, get_default_waitset(),
7856055Srwatson            wait_usec, MKCLOSURE(restart_core, NULL));
7956055Srwatson}
8056055Srwatsonint main(int argc, char *argv[])
81194955Strasz{
82194955Strasz    if (argc == 3) {
83194955Strasz        loopy_core = atoi(argv[1]);
84194955Strasz        core_inc = atoi(argv[2]);
85194955Strasz    }
86194955Strasz    next_core = core_inc;
87194955Strasz    deferred_event_init(&myevent);
88194955Strasz    // spawn loopy on fixed core
89194955Strasz    char *loopy_argv[1] = { "loopy" };
90194955Strasz    struct capref retid;
91194955Strasz    execute_program(loopy_core, 1, loopy_argv, &retid);
92194955Strasz
93194955Strasz    // 2: wait a bit
94194955Strasz    deferred_event_register(&myevent, get_default_waitset(),
95194955Strasz            wait_usec, MKCLOSURE(restart_core, NULL));
96194955Strasz
97194955Strasz    while(true) {
98194955Strasz        event_dispatch(get_default_waitset());
99194955Strasz    }
100194955Strasz    return 0;
101194955Strasz}
102194955Strasz