9ns: Implement fsync with chan_ctl
[akaros.git] / tests / vmm / vthread_test.c
1 /* Copyright (c) 2017 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * vthread_test: mostly create/join/vmcalls */
6
7 #include <vmm/vmm.h>
8 #include <vmm/vthread.h>
9 #include <parlib/stdio.h>
10 #include <parlib/uthread.h>
11
12 enum {
13         MY_VMCALL_TEST1 = VTH_VMCALL_NEXT,
14         MY_VMCALL_TEST2,
15 };
16
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)
21 {
22         switch (vm_tf->tf_rax) {
23         case MY_VMCALL_TEST1:
24                 goto out_ok;
25         }
26         return vth_handle_vmcall(gth, vm_tf);
27 out_ok:
28         vm_tf->tf_rip += 3;
29         return TRUE;
30 };
31
32 static struct virtual_machine vm = {.vmcall = extended_handle_vmcall,
33                                     .mtx = UTH_MUTEX_INIT};
34
35 static void thread_entry(void *arg)
36 {
37         const char nums[] = "123456789";
38
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);
43 }
44
45 int main(int argc, char **argv)
46 {
47         #define NR_VTHS 5
48         struct vthread *vths[NR_VTHS];
49         void *retvals[NR_VTHS];
50
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);
57         }
58
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);
64         }
65         assert(vm.nr_gpcs == NR_VTHS);
66
67         return 0;
68 }