kth: Remove irq_state from sem_.*irqsave's interface
[akaros.git] / kern / src / process.c
index 7c69f77..7197e11 100644 (file)
@@ -577,6 +577,8 @@ static void __set_proc_current(struct proc *p)
        /* We use the pcpui to access 'current' to cut down on the core_id() calls,
         * though who know how expensive/painful they are. */
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       struct proc *old_proc;
+
        /* If the process wasn't here, then we need to load its address space. */
        if (p != pcpui->cur_proc) {
                proc_incref(p, 1);
@@ -585,9 +587,10 @@ static void __set_proc_current(struct proc *p)
                 * previous lcr3 unloaded the previous proc's context.  This should
                 * rarely happen, since we usually proactively leave process context,
                 * but this is the fallback. */
-               if (pcpui->cur_proc)
-                       proc_decref(pcpui->cur_proc);
+               old_proc = pcpui->cur_proc;
                pcpui->cur_proc = p;
+               if (old_proc)
+                       proc_decref(old_proc);
        }
 }
 
@@ -784,28 +787,18 @@ void __proc_startcore(struct proc *p, struct user_context *ctx)
 }
 
 /* Restarts/runs the current_ctx, which must be for the current process, on the
- * core this code executes on.  Calls an internal function to do the work.
+ * core this code executes on.
+ *
+ * For now, we just smp_idle.  We used to do something similar, but customized
+ * for expecting to return to the process.  But it was a source of bugs.  If we
+ * want to optimize for the case where we know we had a process current, then we
+ * can do so here.
  *
- * In case there are pending routine messages, like __death, __preempt, or
- * __notify, we need to run them.  Alternatively, if there are any, we could
- * self_ipi, and run the messages immediately after popping back to userspace,
- * but that would have crappy overhead. */
+ * Note that PRKM currently calls smp_idle() if it ever has a message, so the
+ * value of optimizing may depend on the semantics of PRKM. */
 void proc_restartcore(void)
 {
-       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-
-       assert(!pcpui->cur_kthread->sysc);
-       process_routine_kmsg();
-       /* If there is no owning process, just idle, since we don't know what to do.
-        * This could be because the process had been restarted a long time ago and
-        * has since left the core, or due to a KMSG like __preempt or __death. */
-       if (!pcpui->owning_proc) {
-               abandon_core();
-               smp_idle();
-       }
-       assert(pcpui->cur_ctx);
-       rcu_report_qs();
-       __proc_startcore(pcpui->owning_proc, pcpui->cur_ctx);
+       smp_idle();
 }
 
 /* Helper for proc_destroy.  Disowns any children. */
@@ -879,8 +872,8 @@ void proc_destroy(struct proc *p)
                        // here's how to do it manually
                        if (current == p) {
                                lcr3(boot_cr3);
-                               proc_decref(p);         /* this decref is for the cr3 */
                                current = NULL;
+                               proc_decref(p);         /* this decref is for the cr3 */
                        }
                        #endif
                        send_kernel_message(get_pcoreid(p, 0), __death, (long)p, 0, 0,
@@ -1810,16 +1803,21 @@ void __unmap_vcore(struct proc *p, uint32_t vcoreid)
  * Note this leaves no trace of what was running. This "leaves the process's
  * context.
  *
- * This does not clear the owning proc.  Use the other helper for that. */
-void abandon_core(void)
+ * This does not clear the owning proc.  Use the other helper for that.
+ *
+ * Returns whether or not there was a process present. */
+bool abandon_core(void)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        /* Syscalls that don't return will ultimately call abadon_core(), so we need
         * to make sure we don't think we are still working on a syscall. */
        pcpui->cur_kthread->sysc = 0;
        pcpui->cur_kthread->errbuf = 0; /* just in case */
-       if (pcpui->cur_proc)
+       if (pcpui->cur_proc) {
                __abandon_core();
+               return true;
+       }
+       return false;
 }
 
 /* Helper to clear the core's owning processor and manage refcnting.  Pass in