Add CPU oversubscription test
This commit is contained in:
parent
a818795d88
commit
0746d2a0ec
@ -169,7 +169,7 @@ cpu_update(struct cpu *cpu)
|
||||
|
||||
/* Only virtual cpus can be oversubscribed */
|
||||
if (cpu->nth_running > 1 && !cpu->is_virtual) {
|
||||
err("physical cpu %s has %d thread running at the same time",
|
||||
err("physical cpu %s has %d threads running at the same time",
|
||||
cpu->name, cpu->nth_running);
|
||||
return -1;
|
||||
}
|
||||
|
@ -22,3 +22,4 @@ unit_test(stream.c)
|
||||
unit_test(loom.c)
|
||||
unit_test(thread.c)
|
||||
unit_test(proc.c)
|
||||
unit_test(cpu.c)
|
||||
|
110
test/unit/cpu.c
110
test/unit/cpu.c
@ -1,98 +1,74 @@
|
||||
#include "emu/bay.h"
|
||||
#include "emu/cpu.h"
|
||||
#include "common.h"
|
||||
|
||||
static void
|
||||
test_remove(struct bay *bay)
|
||||
test_oversubscription(void)
|
||||
{
|
||||
struct chan chan;
|
||||
chan_init(&chan, CHAN_SINGLE, "removeme");
|
||||
struct cpu cpu;
|
||||
|
||||
if (bay_register(bay, &chan) != 0)
|
||||
die("bay_register failed\n");
|
||||
int phyid = 0;
|
||||
cpu_init_begin(&cpu, phyid, 0);
|
||||
cpu_set_name(&cpu, "cpu0");
|
||||
cpu_set_gindex(&cpu, 0);
|
||||
if (cpu_init_end(&cpu) != 0)
|
||||
die("cpu_init_end failed");
|
||||
|
||||
if (bay_find(bay, chan.name) == NULL)
|
||||
die("bay_find failed\n");
|
||||
struct proc proc;
|
||||
|
||||
if (bay_remove(bay, &chan) != 0)
|
||||
die("bay_remove failed\n");
|
||||
if (proc_init_begin(&proc, "loom.0/proc.0") != 0)
|
||||
die("proc_init_begin failed");
|
||||
|
||||
if (bay_find(bay, chan.name) != NULL)
|
||||
die("bay_find didn't fail\n");
|
||||
}
|
||||
proc_set_gindex(&proc, 0);
|
||||
|
||||
static void
|
||||
test_duplicate(struct bay *bay)
|
||||
{
|
||||
struct chan chan;
|
||||
chan_init(&chan, CHAN_SINGLE, "dup");
|
||||
/* FIXME: We shouldn't need to recreate a full process to test the CPU
|
||||
* affinity rules */
|
||||
proc.metadata_loaded = 1;
|
||||
|
||||
if (bay_register(bay, &chan) != 0)
|
||||
die("bay_register failed\n");
|
||||
if (proc_init_end(&proc) != 0)
|
||||
die("proc_init_end failed");
|
||||
|
||||
if (bay_register(bay, &chan) == 0)
|
||||
die("bay_register didn't fail\n");
|
||||
struct thread th0, th1;
|
||||
|
||||
if (bay_remove(bay, &chan) != 0)
|
||||
die("bay_remove failed\n");
|
||||
}
|
||||
if (thread_init_begin(&th0, &proc, "loom.0/proc.0/thread.0.ovnistream") != 0)
|
||||
die("thread_init_begin failed");
|
||||
|
||||
static int
|
||||
callback(struct chan *chan, void *ptr)
|
||||
{
|
||||
struct value value;
|
||||
if (chan_read(chan, &value) != 0)
|
||||
die("callback: chan_read failed\n");
|
||||
thread_set_gindex(&th0, 0);
|
||||
|
||||
if (value.type != VALUE_INT64)
|
||||
die("callback: unexpected value type\n");
|
||||
if (thread_init_end(&th0) != 0)
|
||||
die("thread_init_end failed");
|
||||
|
||||
int64_t *ival = ptr;
|
||||
*ival = value.i;
|
||||
if (thread_init_begin(&th1, &proc, "loom.1/proc.1/thread.1.ovnistream") != 0)
|
||||
die("thread_init_begin failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
thread_set_gindex(&th1, 1);
|
||||
|
||||
static void
|
||||
test_callback(struct bay *bay)
|
||||
{
|
||||
struct chan chan;
|
||||
chan_init(&chan, CHAN_SINGLE, "testchan");
|
||||
if (thread_init_end(&th1) != 0)
|
||||
die("thread_init_end failed");
|
||||
|
||||
if (bay_register(bay, &chan) != 0)
|
||||
die("bay_register failed\n");
|
||||
if (thread_set_cpu(&th0, &cpu) != 0)
|
||||
die("thread_set_cpu failed");
|
||||
|
||||
int64_t data = 0;
|
||||
if (bay_add_cb(bay, BAY_CB_DIRTY, &chan, callback, &data) != 0)
|
||||
die("bay_add_cb failed\n");
|
||||
if (thread_set_cpu(&th1, &cpu) != 0)
|
||||
die("thread_set_cpu failed");
|
||||
|
||||
if (data != 0)
|
||||
die("data changed after bay_chan_append_cb\n");
|
||||
if (thread_set_state(&th0, TH_ST_RUNNING) != 0)
|
||||
die("thread_set_state failed");
|
||||
|
||||
if (chan_set(&chan, value_int64(1)) != 0)
|
||||
die("chan_set failed\n");
|
||||
if (thread_set_state(&th1, TH_ST_RUNNING) != 0)
|
||||
die("thread_set_state failed");
|
||||
|
||||
if (data != 0)
|
||||
die("data changed after chan_set\n");
|
||||
if (cpu_add_thread(&cpu, &th0) != 0)
|
||||
die("cpu_add_thread failed");
|
||||
|
||||
/* Now the callback should modify 'data' */
|
||||
if (bay_propagate(bay) != 0)
|
||||
die("bay_propagate failed\n");
|
||||
if (cpu_add_thread(&cpu, &th1) == 0)
|
||||
die("cpu_add_thread didn't fail");
|
||||
|
||||
if (data != 1)
|
||||
die("data didn't change after bay_propagate\n");
|
||||
|
||||
if (bay_remove(bay, &chan) != 0)
|
||||
die("bay_remove failed\n");
|
||||
err("ok");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct bay bay;
|
||||
bay_init(&bay);
|
||||
|
||||
test_remove(&bay);
|
||||
test_duplicate(&bay);
|
||||
test_callback(&bay);
|
||||
test_oversubscription();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user