Add CPU oversubscription test

This commit is contained in:
Rodrigo Arias 2023-02-07 16:17:25 +01:00 committed by Rodrigo Arias Mallo
parent a818795d88
commit 0746d2a0ec
3 changed files with 45 additions and 68 deletions

View File

@ -169,7 +169,7 @@ cpu_update(struct cpu *cpu)
/* Only virtual cpus can be oversubscribed */ /* Only virtual cpus can be oversubscribed */
if (cpu->nth_running > 1 && !cpu->is_virtual) { 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); cpu->name, cpu->nth_running);
return -1; return -1;
} }

View File

@ -22,3 +22,4 @@ unit_test(stream.c)
unit_test(loom.c) unit_test(loom.c)
unit_test(thread.c) unit_test(thread.c)
unit_test(proc.c) unit_test(proc.c)
unit_test(cpu.c)

View File

@ -1,98 +1,74 @@
#include "emu/bay.h" #include "emu/cpu.h"
#include "common.h" #include "common.h"
static void static void
test_remove(struct bay *bay) test_oversubscription(void)
{ {
struct chan chan; struct cpu cpu;
chan_init(&chan, CHAN_SINGLE, "removeme");
if (bay_register(bay, &chan) != 0) int phyid = 0;
die("bay_register failed\n"); 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) struct proc proc;
die("bay_find failed\n");
if (bay_remove(bay, &chan) != 0) if (proc_init_begin(&proc, "loom.0/proc.0") != 0)
die("bay_remove failed\n"); die("proc_init_begin failed");
if (bay_find(bay, chan.name) != NULL) proc_set_gindex(&proc, 0);
die("bay_find didn't fail\n");
}
static void /* FIXME: We shouldn't need to recreate a full process to test the CPU
test_duplicate(struct bay *bay) * affinity rules */
{ proc.metadata_loaded = 1;
struct chan chan;
chan_init(&chan, CHAN_SINGLE, "dup");
if (bay_register(bay, &chan) != 0) if (proc_init_end(&proc) != 0)
die("bay_register failed\n"); die("proc_init_end failed");
if (bay_register(bay, &chan) == 0) struct thread th0, th1;
die("bay_register didn't fail\n");
if (bay_remove(bay, &chan) != 0) if (thread_init_begin(&th0, &proc, "loom.0/proc.0/thread.0.ovnistream") != 0)
die("bay_remove failed\n"); die("thread_init_begin failed");
}
static int thread_set_gindex(&th0, 0);
callback(struct chan *chan, void *ptr)
{
struct value value;
if (chan_read(chan, &value) != 0)
die("callback: chan_read failed\n");
if (value.type != VALUE_INT64) if (thread_init_end(&th0) != 0)
die("callback: unexpected value type\n"); die("thread_init_end failed");
int64_t *ival = ptr; if (thread_init_begin(&th1, &proc, "loom.1/proc.1/thread.1.ovnistream") != 0)
*ival = value.i; die("thread_init_begin failed");
return 0; thread_set_gindex(&th1, 1);
}
static void if (thread_init_end(&th1) != 0)
test_callback(struct bay *bay) die("thread_init_end failed");
{
struct chan chan;
chan_init(&chan, CHAN_SINGLE, "testchan");
if (bay_register(bay, &chan) != 0) if (thread_set_cpu(&th0, &cpu) != 0)
die("bay_register failed\n"); die("thread_set_cpu failed");
int64_t data = 0; if (thread_set_cpu(&th1, &cpu) != 0)
if (bay_add_cb(bay, BAY_CB_DIRTY, &chan, callback, &data) != 0) die("thread_set_cpu failed");
die("bay_add_cb failed\n");
if (data != 0) if (thread_set_state(&th0, TH_ST_RUNNING) != 0)
die("data changed after bay_chan_append_cb\n"); die("thread_set_state failed");
if (chan_set(&chan, value_int64(1)) != 0) if (thread_set_state(&th1, TH_ST_RUNNING) != 0)
die("chan_set failed\n"); die("thread_set_state failed");
if (data != 0) if (cpu_add_thread(&cpu, &th0) != 0)
die("data changed after chan_set\n"); die("cpu_add_thread failed");
/* Now the callback should modify 'data' */ if (cpu_add_thread(&cpu, &th1) == 0)
if (bay_propagate(bay) != 0) die("cpu_add_thread didn't fail");
die("bay_propagate failed\n");
if (data != 1) err("ok");
die("data didn't change after bay_propagate\n");
if (bay_remove(bay, &chan) != 0)
die("bay_remove failed\n");
} }
int main(void) int main(void)
{ {
struct bay bay; test_oversubscription();
bay_init(&bay);
test_remove(&bay);
test_duplicate(&bay);
test_callback(&bay);
return 0; return 0;
} }