akaros/tests/vmm/vthread_test.c
<<
>>
Prefs
   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
  12enum {
  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. */
  19static 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);
  27out_ok:
  28        vm_tf->tf_rip += 3;
  29        return TRUE;
  30};
  31
  32static struct virtual_machine vm = {.vmcall = extended_handle_vmcall,
  33                                    .mtx = UTH_MUTEX_INIT};
  34
  35static 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
  45int 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}
  69