WIP-pop-3000
[akaros.git] / user / parlib / vcore.c
index d2d9ef4..3898aed 100644 (file)
@@ -37,16 +37,6 @@ void __attribute__((noreturn)) __vcore_entry(void)
 }
 void vcore_entry(void) __attribute__((weak, alias ("__vcore_entry")));
 
-static void __fake_start(void)
-{
-}
-void _start(void) __attribute__((weak, alias ("__fake_start")));
-
-bool __in_fake_parlib(void)
-{
-       return _start == __fake_start;
-}
-
 /* TODO: probably don't want to dealloc.  Considering caching */
 static void free_transition_tls(int id)
 {
@@ -102,9 +92,15 @@ static int allocate_vcore_stack(int id)
        if (vcpd->vcore_stack)
                return 0; // reuse old stack
 
+// XXX consider adding a guard page.  yeah, it fucks with the VMR map
+//             at least for debugging
+//     force_a_page_fault = ACCESS_ONCE(*(int*)(pt->stacktop - sizeof(int)));
+//                     also, can change this in pth code to use the syscall_async (faster)
+//     syscall_async(&uthread->local_sysc, SYS_populate_va, aux, 1);
+
        void* stackbot = mmap(0, TRANSITION_STACK_SIZE,
-                             PROT_READ|PROT_WRITE|PROT_EXEC,
-                             MAP_POPULATE|MAP_ANONYMOUS, -1, 0);
+                             PROT_READ | PROT_WRITE | PROT_EXEC,
+                             MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 
        if(stackbot == MAP_FAILED)
                return -1; // errno set by mmap
@@ -152,7 +148,8 @@ static void prep_vcore_0(void)
 
        mmap_block = (uintptr_t)mmap(0, PGSIZE * 4,
                                     PROT_WRITE | PROT_READ,
-                                    MAP_POPULATE | MAP_ANONYMOUS, -1, 0);
+                                    MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE,
+                                    -1, 0);
        assert((void*)mmap_block != MAP_FAILED);
        __prep_vcore(0, mmap_block);
 }
@@ -163,7 +160,8 @@ static void prep_remaining_vcores(void)
 
        mmap_block = (uintptr_t)mmap(0, PGSIZE * 4 * (max_vcores() - 1),
                                     PROT_WRITE | PROT_READ,
-                                    MAP_POPULATE | MAP_ANONYMOUS, -1, 0);
+                                    MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE,
+                                    -1, 0);
        assert((void*)mmap_block != MAP_FAILED);
        for (int i = 1; i < max_vcores(); i++)
                __prep_vcore(i, mmap_block + 4 * (i - 1) * PGSIZE);
@@ -178,10 +176,14 @@ static void vcore_libc_init(void)
         * program. */
 }
 
-void __attribute__((constructor)) vcore_lib_init(void)
+/* We need to separate the guts of vcore_lib_ctor() into a separate function,
+ * since the uthread ctor depends on this ctor running first.
+ *
+ * Also note that if you make a global ctor (not static, like this used to be),
+ * any shared objects that you load when the binary is built with -rdynamic will
+ * run the global ctor from the binary, not the one from the .so. */
+void vcore_lib_init(void)
 {
-       if (__in_fake_parlib())
-               return;
        /* Note this is racy, but okay.  The first time through, we are _S.
         * Also, this is the "lowest" level constructor for now, so we don't need
         * to call any other init functions after our run_once() call. This may
@@ -195,6 +197,13 @@ void __attribute__((constructor)) vcore_lib_init(void)
        vcore_libc_init();
 }
 
+static void __attribute__((constructor)) vcore_lib_ctor(void)
+{
+       if (__in_fake_parlib())
+               return;
+       vcore_lib_init();
+}
+
 /* Helper functions used to reenter at the top of a vcore's stack for an
  * arbitrary function */
 static void __attribute__((noinline, noreturn)) 
@@ -518,3 +527,14 @@ void __attribute__((noreturn)) vcore_yield_or_restart(void)
        set_stack_pointer((void*)vcpd->vcore_stack);
        vcore_entry();
 }
+
+void vcore_wake(uint32_t vcoreid, bool force_ipi)
+{
+       struct preempt_data *vcpd = vcpd_of(vcoreid);
+
+       vcpd->notif_pending = true;
+       if (vcoreid == vcore_id())
+               return;
+       if (force_ipi || !arch_has_mwait())
+               sys_self_notify(vcoreid, EV_NONE, 0, true);
+}