| 2106 | } |
| 2107 | |
| 2108 | int vcpu_init(uint64_t flags) { |
| 2109 | uint64_t FLAGS = VCPU_ENABLE_ACTIVE_WORK_STEALING | |
| 2110 | VCPU_ENABLE_PASSIVE_WORK_STEALING; |
| 2111 | if (unlikely(flags & ~FLAGS)) |
| 2112 | LOG_ERROR_RETURN(EINVAL, -1, "invalid flags ", HEX(flags)); |
| 2113 | if (unlikely(PAGE_SIZE == 0)) |
| 2114 | PAGE_SIZE = getpagesize(); |
| 2115 | RunQ rq; |
| 2116 | if (rq.current) return -1; // re-init has no side-effect |
| 2117 | char* ptr = nullptr; |
| 2118 | int err = posix_memalign((void**)&ptr, 64, sizeof(vcpu_t)); |
| 2119 | if (unlikely(err)) |
| 2120 | LOG_ERROR_RETURN(err, -1, "Failed to allocate vcpu ", ERRNO(err)); |
| 2121 | |
| 2122 | auto th = *rq.pc = new thread; |
| 2123 | th->vcpu = (vcpu_t*)ptr; |
| 2124 | th->state = states::RUNNING; |
| 2125 | th->init_main_thread_stack(); |
| 2126 | auto vcpu = new (ptr) vcpu_t(uint8_t(flags & FLAGS)); |
| 2127 | vcpu->idle_worker = thread_create(&idler, nullptr); |
| 2128 | thread_enable_join(vcpu->idle_worker); |
| 2129 | if_update_now(true); |
| 2130 | return ++_n_vcpu; |
| 2131 | } |
| 2132 | |
| 2133 | int vcpu_fini() { |
| 2134 | RunQ rq; |