1 /* Copyright (c) 2017 Google Inc.
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * See LICENSE for details.
5 * vthread_test: mostly create/join/vmcalls */
8 #include <vmm/vthread.h>
9 #include <parlib/stdio.h>
10 #include <parlib/uthread.h>
13 MY_VMCALL_TEST1 = VTH_VMCALL_NEXT,
17 /* Here's how you can make your own vmcalls and still use the vth vmcalls for
18 * the stuff you don't want to reimplement. */
19 static bool extended_handle_vmcall(struct guest_thread *gth,
20 struct vm_trapframe *vm_tf)
22 switch (vm_tf->tf_rax) {
26 return vth_handle_vmcall(gth, vm_tf);
32 static struct virtual_machine vm = {.vmcall = extended_handle_vmcall,
33 .mtx = UTH_MUTEX_INIT};
35 static void thread_entry(void *arg)
37 const char nums[] = "123456789";
39 for (int i = 0; i < sizeof(nums); i++)
40 vmcall(VTH_VMCALL_PRINTC, nums[i]);
41 vmcall(MY_VMCALL_TEST1);
42 vmcall(VTH_VMCALL_EXIT, arg, 0, 0, 0);
45 int main(int argc, char **argv)
48 struct vthread *vths[NR_VTHS];
49 void *retvals[NR_VTHS];
51 /* Tests multiple threads at once */
52 for (long i = 0; i < NR_VTHS; i++)
53 vths[i] = vthread_create(&vm, thread_entry, (void*)i);
54 for (long i = 0; i < NR_VTHS; i++) {
55 vthread_join(vths[i], &retvals[i]);
56 assert(retvals[i] == (void*)i);
59 /* Tests reuse / GPC leakage */
60 for (long i = 0; i < NR_VTHS * 2; i++) {
61 vths[0] = vthread_create(&vm, thread_entry, (void*)i);
62 vthread_join(vths[0], &retvals[0]);
63 assert(retvals[0] == (void*)i);
65 assert(vm.nr_gpcs == NR_VTHS);