#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 <lunaix/usrscope.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));
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/<arch>/interrupt.S.inc to avoid
disaster!
*/
struct
{
- isr_param* intr_ctx;
+ struct hart_state* hstate;
ptr_t ustack_top;
}; // *critical section
struct mm_region* ustack; // process local user stack (NULL for kernel thread)
};
+ struct thread_stats stats;
+
struct haybed sleep;
struct proc_info* process;
pid_t pgid;
time_t created;
+ uid_t euid;
+ uid_t suid;
+ gid_t egid;
+ gid_t sgid;
+
+ struct user_scope uscope;
+ struct v_dnode* root;
+
int state;
int exit_code;
};
struct proc_mm* mm;
- struct sigregister* sigreg;
+ struct sigregistry* sigreg;
struct v_fdtable* fdtable;
struct v_dnode* cwd;
struct {
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
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);
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 =========
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];
}
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;
+}
+
+static inline struct user_scope*
+current_user_scope()
+{
+ return &__current->uscope;
+}
+
+static inline uid_t must_inline
+current_euid()
+{
+ return __current->euid;
+}
+
+static inline bool must_inline
+current_is_root()
+{
+ return current_euid() == 0;
+}
+
+static inline gid_t must_inline
+current_egid()
+{
+ return __current->egid;
+}
+
+static inline void must_inline
+current_set_egid(gid_t gid)
+{
+ __current->egid = gid;
+}
+
+static inline void must_inline
+current_set_euid(uid_t uid)
+{
+ __current->euid = uid;
+}
#endif /* __LUNAIX_PROCESS_H */