add btrie_map() for allocating free slot, remove isrm
[lunaix-os.git] / lunaix-os / includes / lunaix / process.h
index 78756de7ab5f121a1c088e665dc6354ded813e23..86e485e27a599d78c051d1d9879e3f4b8153f87c 100644 (file)
@@ -6,13 +6,13 @@
 #include <lunaix/fs.h>
 #include <lunaix/iopoll.h>
 #include <lunaix/mm/mm.h>
-#include <lunaix/mm/page.h>
+#include <lunaix/mm/pagetable.h>
 #include <lunaix/mm/region.h>
 #include <lunaix/signal.h>
 #include <lunaix/timer.h>
 #include <lunaix/types.h>
 #include <lunaix/spike.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
 #include <stdint.h>
 
 
 #define PS_GrDT (PS_TERMNAT | PS_DESTROY)
 #define PS_Rn (PS_RUNNING | PS_CREATED)
 
-#define proc_terminated(proc) (((proc)->state) & PS_GrDT)
-#define proc_hanged(proc) (((proc)->state) & PS_BLOCKED)
-#define proc_runnable(proc) (!(proc)->state || !(((proc)->state) & ~PS_Rn))
+#define proc_terminated(proc) \
+            (!(proc) || ((proc)->state) & PS_GrDT)
+#define proc_hanged(proc) \
+            ((proc)  && ((proc)->state) & PS_BLOCKED)
+#define proc_runnable(proc) \
+            ((proc) && (!(proc)->state || !(((proc)->state) & ~PS_Rn)))
 
 
-#define TH_DETACHED 0b0001
+#define TH_DETACHED         0b00000001
+#define TH_STALLED          0b00000010
 
 #define thread_detached(th) ((th)->flags & TH_DETACHED)
 #define detach_thread(th) ((th)->flags |= TH_DETACHED)
 
+#define thread_flags_set(th, flag)      ((th)->flags |= (flag))
+#define thread_flags_clear(th, flag)    ((th)->flags &= ~(flag))
+#define thread_flags_test(th, flag)     ((th)->flags & (flag))
+#define thread_flags_test_all(th, flag) (((th)->flags & (flag)) == (flag))
+
 struct proc_sig
 {
     int sig_num;
     void* sigact;
     void* sighand;
-    isr_param* saved_ictx;
+    struct hart_state* saved_hstate;
 } __attribute__((packed));
 
 
@@ -72,16 +81,44 @@ struct haybed {
     time_t alarm_time;
 };
 
+struct thread_stats
+{
+    // number of times the thread entering kernel space involuntarily
+    unsigned long entry_count_invol;
+    // number of times the thread entering kernel space voluntarily
+    unsigned long entry_count_vol;
+    
+    // number of times the thread is preempted in kerenl space
+    unsigned long kpreempt_count;
+
+    // timestamp of last time kernel entry
+    time_t last_entry;
+    // timestamp of last time kernel reentry
+    time_t last_reentry;
+
+    // timestamp of last time kernel leave
+    time_t last_leave;
+    // timestamp of last time the thread is resumed
+    time_t last_resume;
+    
+    union {
+        struct {
+            bool at_user;
+        };
+        int flags;
+    };
+};
+
 struct thread
 {
     /*
         Any change to *critical section*, including layout, size
-        must be reflected in arch/i386/interrupt.S.inc to avoid
+        must be reflected in arch/x86/interrupt.S.inc to avoid
         disaster!
      */
     struct
     {
-        isr_param* intr_ctx;
+        struct hart_state* hstate;
         ptr_t ustack_top;
     };                              // *critical section
 
@@ -99,6 +136,8 @@ struct thread
         struct mm_region* ustack;   // process local user stack (NULL for kernel thread)
     };
 
+    struct thread_stats stats;
+
     struct haybed sleep;
 
     struct proc_info* process;
@@ -133,7 +172,7 @@ struct proc_info
     };
 
     struct proc_mm* mm;
-    struct sigregister* sigreg;
+    struct sigregistry* sigreg;
     struct v_fdtable* fdtable;
     struct v_dnode* cwd;
     struct {
@@ -167,19 +206,26 @@ set_current_executing(struct thread* thread)
 static inline struct proc_mm* 
 vmspace(struct proc_info* proc) 
 {
-    return proc->mm;
+    return proc ? proc->mm : NULL;
 }
 
 static inline ptr_t
 vmroot(struct proc_info* proc) 
 {
-    return proc->mm->vmroot;
+    return proc ? proc->mm->vmroot : 0;
 }
 
 static inline vm_regions_t* 
 vmregions(struct proc_info* proc) 
 {
-    return &proc->mm->regions;
+    return proc ? &proc->mm->regions : NULL;
+}
+
+
+static inline unsigned int
+procvm_asid(struct proc_mm* mm)
+{
+    return mm->proc->pid;
 }
 
 static inline void
@@ -302,7 +348,7 @@ struct thread*
 alloc_thread(struct proc_info* process);
 
 void
-destory_thread(ptr_t vm_mnt, struct thread* thread);
+destory_thread(struct thread* thread);
 
 void
 terminate_thread(struct thread* thread, ptr_t val);
@@ -311,26 +357,27 @@ void
 terminate_current_thread(ptr_t val);
 
 struct thread*
-create_thread(struct proc_info* proc, ptr_t vm_mnt, bool with_ustack);
+create_thread(struct proc_info* proc, bool with_ustack);
 
 void
-start_thread(struct thread* th, ptr_t vm_mnt, ptr_t entry);
+start_thread(struct thread* th, ptr_t entry);
 
 static inline void
 spawn_kthread(ptr_t entry) {
     assert(kernel_process(__current));
 
-    struct thread* th = create_thread(__current, VMS_SELF, false);
+    struct thread* th = create_thread(__current, false);
     
     assert(th);
-    start_thread(th, VMS_SELF, entry);
+    start_thread(th, entry);
+    detach_thread(th);
 }
 
 void 
 exit_thread(void* val);
 
 void
-thread_release_mem(struct thread* thread, ptr_t vm_mnt);
+thread_release_mem(struct thread* thread);
 
 /* 
     ========= Signal =========
@@ -344,7 +391,7 @@ thread_release_mem(struct thread* thread, ptr_t vm_mnt);
 static inline struct sigact*
 active_signal(struct thread* thread) {
     struct sigctx* sigctx = &thread->sigctx;
-    struct sigregister* sigreg = thread->process->sigreg;
+    struct sigregistry* sigreg = thread->process->sigreg;
     return sigreg->signals[sigctx->sig_active];
 } 
 
@@ -374,5 +421,47 @@ proc_setsignal(struct proc_info* proc, signum_t signum);
 void
 thread_setsignal(struct thread* thread, signum_t signum);
 
+void
+thread_stats_update(bool inbound, bool voluntary);
+
+static inline void
+thread_stats_update_entering(bool voluntary)
+{
+    thread_stats_update(true, voluntary);
+}
+
+static inline void
+thread_stats_update_leaving()
+{
+    thread_stats_update(false, true);
+}
+
+static inline void
+thread_stats_update_kpreempt()
+{
+    current_thread->stats.kpreempt_count++;
+}
+
+static inline void
+thread_stats_reset_kpreempt()
+{
+    current_thread->stats.kpreempt_count = 0;
+}
+
+static inline ticks_t
+thread_stats_kernel_elapse(struct thread* thread)
+{
+    return clock_systime() - thread->stats.last_reentry;
+}
+
+static inline ticks_t
+thread_stats_user_elapse(struct thread* thread)
+{
+    struct thread_stats* stats;
+    stats = &thread->stats;
+
+    return stats->last_entry - stats->last_leave;
+}
+
 
 #endif /* __LUNAIX_PROCESS_H */