Spinlock save cpu flags
This commit is contained in:
@@ -12,43 +12,47 @@
|
||||
#include <sys/smp.h>
|
||||
|
||||
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx) {
|
||||
uint64_t fr, fssq;
|
||||
|
||||
struct proc_mail* mail = &resource->u.mail;
|
||||
|
||||
spin_lock (&mail->resource->lock);
|
||||
spin_lock (&mail->resource->lock, &fr);
|
||||
|
||||
ringbuffer_fini (&mail->ringbuffer);
|
||||
|
||||
spin_lock (&mail->send_sq.lock);
|
||||
spin_lock (&mail->send_sq.lock, &fssq);
|
||||
|
||||
while (mail->send_sq.proc_list != NULL) {
|
||||
struct list_node_link* node = mail->send_sq.proc_list;
|
||||
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
|
||||
struct proc* suspended_proc = sq_entry->proc;
|
||||
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->send_sq.lock, fssq);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
|
||||
proc_sq_resume (suspended_proc, sq_entry, rctx);
|
||||
|
||||
spin_lock (&mail->resource->lock);
|
||||
spin_lock (&mail->send_sq.lock);
|
||||
spin_lock (&mail->resource->lock, &fr);
|
||||
spin_lock (&mail->send_sq.lock, &fssq);
|
||||
}
|
||||
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->send_sq.lock, fssq);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
}
|
||||
|
||||
void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
|
||||
void* data, size_t data_size) {
|
||||
spin_lock (&mail->resource->lock);
|
||||
uint64_t fr, frsq, fp;
|
||||
|
||||
spin_lock (&mail->resource->lock, &fr);
|
||||
|
||||
/* mail full */
|
||||
if (mail->ringbuffer.count == mail->ringbuffer.capacity) {
|
||||
proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx);
|
||||
proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, fr, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock (&mail->recv_sq.lock);
|
||||
spin_lock (&mail->recv_sq.lock, &frsq);
|
||||
|
||||
/* if receiver available, hand off directly */
|
||||
struct list_node_link* node = mail->recv_sq.proc_list;
|
||||
@@ -57,10 +61,10 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul
|
||||
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
|
||||
struct proc* resumed_proc = sq_entry->proc;
|
||||
|
||||
spin_unlock (&mail->recv_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->recv_sq.lock, frsq);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
|
||||
spin_lock (&resumed_proc->lock);
|
||||
spin_lock (&resumed_proc->lock, &fp);
|
||||
|
||||
if (resumed_proc->mail_recv_buffer != NULL) {
|
||||
size_t copy_size = min (data_size, resumed_proc->mail_recv_size);
|
||||
@@ -70,13 +74,13 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul
|
||||
resumed_proc->mail_recv_size = 0;
|
||||
}
|
||||
|
||||
spin_unlock (&resumed_proc->lock);
|
||||
spin_unlock (&resumed_proc->lock, fp);
|
||||
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock (&mail->recv_sq.lock);
|
||||
spin_unlock (&mail->recv_sq.lock, frsq);
|
||||
|
||||
/* mail is empty and nobody is waiting */
|
||||
void* mesg = malloc (data_size);
|
||||
@@ -86,17 +90,19 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul
|
||||
ringbuffer_push (struct mail_packet, &mail->ringbuffer, packet);
|
||||
}
|
||||
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
}
|
||||
|
||||
void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
|
||||
void* recv_buffer, size_t recv_size) {
|
||||
spin_lock (&proc->lock);
|
||||
uint64_t fp, fr, fssq;
|
||||
|
||||
spin_lock (&proc->lock, &fp);
|
||||
proc->mail_recv_buffer = recv_buffer;
|
||||
proc->mail_recv_size = recv_size;
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
|
||||
spin_lock (&mail->resource->lock);
|
||||
spin_lock (&mail->resource->lock, &fr);
|
||||
|
||||
/* consume mesg if available */
|
||||
if (mail->ringbuffer.count > 0) {
|
||||
@@ -106,7 +112,7 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche
|
||||
free (packet.packet_buffer);
|
||||
|
||||
/* check for suspended sender */
|
||||
spin_lock (&mail->send_sq.lock);
|
||||
spin_lock (&mail->send_sq.lock, &fssq);
|
||||
|
||||
struct list_node_link* node = mail->send_sq.proc_list;
|
||||
|
||||
@@ -114,19 +120,19 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche
|
||||
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
|
||||
struct proc* resumed_proc = sq_entry->proc;
|
||||
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->send_sq.lock, fssq);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
spin_unlock (&mail->send_sq.lock, fssq);
|
||||
spin_unlock (&mail->resource->lock, fr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* nothing to receive */
|
||||
proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, rctx);
|
||||
proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, fr, rctx);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
#include <sys/spin_lock.h>
|
||||
|
||||
void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&proc->procgroup->lock);
|
||||
uint64_t fpg, fr;
|
||||
|
||||
spin_lock (&proc->procgroup->lock, &fpg);
|
||||
|
||||
struct rb_node_link* rnode;
|
||||
rbtree_first (&proc->procgroup->resource_tree, rnode);
|
||||
@@ -25,30 +27,32 @@ void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
|
||||
rnode = next;
|
||||
|
||||
spin_lock (&resource->lock);
|
||||
spin_lock (&resource->lock, &fr);
|
||||
|
||||
if (resource->type != PR_MUTEX) {
|
||||
spin_unlock (&resource->lock);
|
||||
spin_unlock (&resource->lock, fr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resource->u.mutex.owner == proc && resource->u.mutex.locked) {
|
||||
spin_unlock (&resource->lock);
|
||||
spin_unlock (&resource->lock, fr);
|
||||
|
||||
proc_mutex_unlock (proc, &resource->u.mutex, rctx);
|
||||
}
|
||||
|
||||
spin_unlock (&resource->lock);
|
||||
spin_unlock (&resource->lock, fr);
|
||||
}
|
||||
|
||||
spin_unlock (&proc->procgroup->lock);
|
||||
spin_unlock (&proc->procgroup->lock, fpg);
|
||||
}
|
||||
|
||||
void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx) {
|
||||
uint64_t fr, fsq;
|
||||
|
||||
struct proc_mutex* mutex = &resource->u.mutex;
|
||||
|
||||
spin_lock (&mutex->resource->lock);
|
||||
spin_lock (&mutex->suspension_q.lock);
|
||||
spin_lock (&mutex->resource->lock, &fr);
|
||||
spin_lock (&mutex->suspension_q.lock, &fsq);
|
||||
|
||||
while (mutex->suspension_q.proc_list != NULL) {
|
||||
struct list_node_link* node = mutex->suspension_q.proc_list;
|
||||
@@ -56,45 +60,49 @@ void proc_cleanup_resource_mutex (struct proc_resource* resource, struct resched
|
||||
struct proc* suspended_proc = sq_entry->proc;
|
||||
|
||||
/* we will relock during resume */
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->suspension_q.lock, fsq);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
|
||||
proc_sq_resume (suspended_proc, sq_entry, rctx);
|
||||
|
||||
/* reacquire */
|
||||
spin_lock (&mutex->resource->lock);
|
||||
spin_lock (&mutex->suspension_q.lock);
|
||||
spin_lock (&mutex->resource->lock, &fr);
|
||||
spin_lock (&mutex->suspension_q.lock, &fsq);
|
||||
}
|
||||
|
||||
mutex->locked = false;
|
||||
mutex->owner = NULL;
|
||||
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->suspension_q.lock, fsq);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
}
|
||||
|
||||
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&mutex->resource->lock);
|
||||
uint64_t fr;
|
||||
|
||||
spin_lock (&mutex->resource->lock, &fr);
|
||||
|
||||
if (!mutex->locked || mutex->owner == proc) {
|
||||
mutex->locked = true;
|
||||
mutex->owner = proc;
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
return;
|
||||
}
|
||||
|
||||
proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, rctx);
|
||||
proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, fr, rctx);
|
||||
}
|
||||
|
||||
void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&mutex->resource->lock);
|
||||
uint64_t fr, fsq;
|
||||
|
||||
spin_lock (&mutex->resource->lock, &fr);
|
||||
|
||||
if (mutex->owner != proc) {
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock (&mutex->suspension_q.lock);
|
||||
spin_lock (&mutex->suspension_q.lock, &fsq);
|
||||
|
||||
struct list_node_link* node = mutex->suspension_q.proc_list;
|
||||
|
||||
@@ -105,8 +113,8 @@ void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct resc
|
||||
mutex->owner = resumed_proc;
|
||||
mutex->locked = true;
|
||||
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->suspension_q.lock, fsq);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
@@ -115,6 +123,6 @@ void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct resc
|
||||
mutex->locked = false;
|
||||
mutex->owner = NULL;
|
||||
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
spin_unlock (&mutex->suspension_q.lock, fsq);
|
||||
spin_unlock (&mutex->resource->lock, fr);
|
||||
}
|
||||
|
||||
@@ -177,21 +177,25 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char*
|
||||
}
|
||||
|
||||
struct proc* proc_find_pid (int pid) {
|
||||
uint64_t fpt;
|
||||
|
||||
struct proc* proc = NULL;
|
||||
|
||||
spin_lock (&proc_tree_lock);
|
||||
spin_lock (&proc_tree_lock, &fpt);
|
||||
rbtree_find (struct proc, &proc_tree, pid, proc, proc_tree_link, pid);
|
||||
spin_unlock (&proc_tree_lock);
|
||||
spin_unlock (&proc_tree_lock, fpt);
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx) {
|
||||
uint64_t fpt, fc, fp;
|
||||
|
||||
struct cpu* cpu = register_cpu != NULL ? register_cpu : cpu_find_lightest ();
|
||||
|
||||
spin_lock (&proc_tree_lock);
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&proc_tree_lock, &fpt);
|
||||
spin_lock (&cpu->lock, &fc);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
proc->cpu = cpu;
|
||||
|
||||
@@ -202,15 +206,17 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu
|
||||
if (cpu->proc_current == NULL)
|
||||
cpu->proc_current = proc;
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&proc_tree_lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&cpu->lock, fc);
|
||||
spin_unlock (&proc_tree_lock, fpt);
|
||||
|
||||
rctx_insert_cpu (rctx, cpu);
|
||||
}
|
||||
|
||||
/* caller holds cpu->lock */
|
||||
static struct proc* proc_find_sched (struct cpu* cpu) {
|
||||
uint64_t fp;
|
||||
|
||||
if (!cpu->proc_run_q)
|
||||
return NULL;
|
||||
|
||||
@@ -229,16 +235,16 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
|
||||
do {
|
||||
struct proc* proc = list_entry (current, struct proc, cpu_run_q_link);
|
||||
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
int state = proc->state;
|
||||
|
||||
if (state == PROC_READY && !(proc->flags & PROC_KPROC)) {
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
return proc;
|
||||
}
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
|
||||
current = current->next ? current->next : cpu->proc_run_q;
|
||||
} while (current != start);
|
||||
@@ -249,36 +255,39 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
|
||||
void proc_sched (void) {
|
||||
struct proc* next = NULL;
|
||||
struct cpu* cpu = thiscpu;
|
||||
uint64_t fc;
|
||||
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&cpu->lock, &fc);
|
||||
|
||||
next = proc_find_sched (cpu);
|
||||
|
||||
if (next) {
|
||||
cpu->proc_current = next;
|
||||
|
||||
do_sched (next, &cpu->lock);
|
||||
do_sched (next, &cpu->lock, fc);
|
||||
} else {
|
||||
cpu->proc_current = NULL;
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&cpu->lock, fc);
|
||||
|
||||
spin ();
|
||||
}
|
||||
}
|
||||
|
||||
void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&proc->lock);
|
||||
uint64_t fp, fc, fpt;
|
||||
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
if ((proc->flags & PROC_KPROC)) {
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
return;
|
||||
}
|
||||
|
||||
struct cpu* cpu = proc->cpu;
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&cpu->lock, &fc);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
proc->state = PROC_DEAD;
|
||||
proc->cpu = NULL;
|
||||
@@ -288,16 +297,16 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
if (cpu->proc_current == proc)
|
||||
cpu->proc_current = NULL;
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&cpu->lock, fc);
|
||||
|
||||
spin_lock (&proc_tree_lock);
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&proc_tree_lock, &fpt);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
rbtree_delete (&proc_tree, &proc->proc_tree_link);
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc_tree_lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&proc_tree_lock, fpt);
|
||||
|
||||
proc_cleanup (proc, rctx);
|
||||
|
||||
@@ -307,7 +316,7 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
}
|
||||
|
||||
void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* wait_proc) {
|
||||
proc_sq_suspend (proc, &wait_proc->done_sq, NULL, rctx);
|
||||
proc_sq_suspend (proc, &wait_proc->done_sq, NULL, 0, rctx);
|
||||
}
|
||||
|
||||
static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) {
|
||||
@@ -323,6 +332,8 @@ static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx)
|
||||
}
|
||||
|
||||
void proc_init (void) {
|
||||
uint64_t fc;
|
||||
|
||||
#if defined(__x86_64__)
|
||||
irq_attach (&proc_irq_sched, NULL, SCHED_PREEMPT_TIMER);
|
||||
irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED);
|
||||
@@ -338,6 +349,6 @@ void proc_init (void) {
|
||||
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
|
||||
proc_register (init, thiscpu, &rctx);
|
||||
|
||||
spin_lock (&spin_proc->cpu->lock);
|
||||
do_sched (spin_proc, &spin_proc->cpu->lock);
|
||||
spin_lock (&spin_proc->cpu->lock, &fc);
|
||||
do_sched (spin_proc, &spin_proc->cpu->lock, fc);
|
||||
}
|
||||
|
||||
@@ -22,25 +22,29 @@ static struct id_alloc pgid_alloc;
|
||||
void procgroup_pgid_alloc_init (void) { id_alloc_init (&pgid_alloc, PGIDS_MAX); }
|
||||
|
||||
struct procgroup* procgroup_find (int pgid) {
|
||||
uint64_t fpgt;
|
||||
|
||||
struct procgroup* procgroup = NULL;
|
||||
|
||||
spin_lock (&procgroup_tree_lock);
|
||||
spin_lock (&procgroup_tree_lock, &fpgt);
|
||||
rbtree_find (struct procgroup, &procgroup_tree, pgid, procgroup, procgroup_tree_link, pgid);
|
||||
spin_unlock (&procgroup_tree_lock);
|
||||
spin_unlock (&procgroup_tree_lock, fpgt);
|
||||
|
||||
return procgroup;
|
||||
}
|
||||
|
||||
uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pages, uint32_t flags,
|
||||
uintptr_t* out_paddr) {
|
||||
spin_lock (&procgroup->lock);
|
||||
uint64_t fpg;
|
||||
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
|
||||
vaddr = (vaddr == 0) ? procgroup->map_base : vaddr;
|
||||
|
||||
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
||||
|
||||
if (mapping == NULL) {
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -48,7 +52,7 @@ uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pa
|
||||
|
||||
if (paddr == PMM_ALLOC_ERR) {
|
||||
free (mapping);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -68,12 +72,13 @@ uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pa
|
||||
mm_map_page (&procgroup->pd, ppage, vpage, flags);
|
||||
}
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t pages) {
|
||||
uint64_t fpg;
|
||||
size_t unmap_size = pages * PAGE_SIZE;
|
||||
uintptr_t end_vaddr = start_vaddr + unmap_size;
|
||||
|
||||
@@ -85,7 +90,7 @@ bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t
|
||||
if (tail_mapping == NULL)
|
||||
return false;
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
|
||||
list_foreach (procgroup->mappings, mapping_link, mapping_link_tmp) {
|
||||
struct proc_mapping* mapping =
|
||||
@@ -138,12 +143,14 @@ bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t
|
||||
mm_unmap_page (&procgroup->pd, vpage);
|
||||
}
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct procgroup* procgroup_create (void) {
|
||||
uint64_t fpgt;
|
||||
|
||||
struct procgroup* procgroup = malloc (sizeof (*procgroup));
|
||||
if (procgroup == NULL) {
|
||||
return NULL;
|
||||
@@ -175,33 +182,37 @@ struct procgroup* procgroup_create (void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spin_lock (&procgroup_tree_lock);
|
||||
spin_lock (&procgroup_tree_lock, &fpgt);
|
||||
rbtree_insert (struct procgroup, &procgroup_tree, &procgroup->procgroup_tree_link,
|
||||
procgroup_tree_link, pgid);
|
||||
spin_unlock (&procgroup_tree_lock);
|
||||
spin_unlock (&procgroup_tree_lock, fpgt);
|
||||
|
||||
return procgroup;
|
||||
}
|
||||
|
||||
void procgroup_attach (struct procgroup* procgroup, struct proc* proc) {
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&proc->lock);
|
||||
uint64_t fpg, fp;
|
||||
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
rbtree_insert (struct proc, &procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link,
|
||||
procgroup_memb_tree_link, pid);
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
}
|
||||
|
||||
static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&procgroup_tree_lock);
|
||||
spin_lock (&procgroup->lock);
|
||||
uint64_t fpg, fpgt;
|
||||
|
||||
spin_lock (&procgroup_tree_lock, &fpgt);
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
|
||||
rbtree_delete (&procgroup_tree, &procgroup->procgroup_tree_link);
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup_tree_lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
spin_unlock (&procgroup_tree_lock, fpgt);
|
||||
|
||||
/* delete resources */
|
||||
struct rb_node_link* rnode;
|
||||
@@ -239,14 +250,16 @@ static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx
|
||||
|
||||
void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
|
||||
struct reschedule_ctx* rctx) {
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&proc->lock);
|
||||
uint64_t fpg, fp;
|
||||
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
rbtree_delete (&procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link);
|
||||
struct rb_node_link* memb_tree = procgroup->memb_proc_tree;
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
if (memb_tree == NULL) {
|
||||
procgroup_delete (procgroup, rctx);
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
#include <sys/debug.h>
|
||||
|
||||
struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid) {
|
||||
uint64_t fr;
|
||||
|
||||
struct proc_resource* resource = NULL;
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&procgroup->lock, &fr);
|
||||
rbtree_find (struct proc_resource, &procgroup->resource_tree, rid, resource, resource_tree_link,
|
||||
rid);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fr);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) {
|
||||
uint64_t fpg;
|
||||
|
||||
struct proc_resource* resource;
|
||||
|
||||
resource = malloc (sizeof (*resource));
|
||||
@@ -35,13 +39,13 @@ struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) {
|
||||
|
||||
memset (resource, 0, sizeof (*resource));
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
|
||||
resource->rid = id_alloc (&procgroup->rid_alloc);
|
||||
|
||||
if (resource->rid < 0) {
|
||||
free (resource);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -53,12 +57,14 @@ struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) {
|
||||
rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link,
|
||||
resource_tree_link, rid);
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) {
|
||||
uint64_t fpg;
|
||||
|
||||
struct proc_resource* resource;
|
||||
|
||||
resource = malloc (sizeof (*resource));
|
||||
@@ -67,13 +73,13 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) {
|
||||
|
||||
memset (resource, 0, sizeof (*resource));
|
||||
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
|
||||
resource->rid = id_alloc (&procgroup->rid_alloc);
|
||||
|
||||
if (resource->rid < 0) {
|
||||
free (resource);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -85,28 +91,30 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) {
|
||||
if (!ringbuffer_init (&resource->u.mail.ringbuffer, PROC_MAIL_MAX, sizeof (struct mail_packet))) {
|
||||
id_free (&procgroup->rid_alloc, resource->rid);
|
||||
free (resource);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link,
|
||||
resource_tree_link, rid);
|
||||
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void proc_delete_resource (struct procgroup* procgroup, struct proc_resource* resource,
|
||||
struct reschedule_ctx* rctx) {
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&resource->lock);
|
||||
uint64_t fr, fpg;
|
||||
|
||||
spin_lock (&procgroup->lock, &fpg);
|
||||
spin_lock (&resource->lock, &fr);
|
||||
|
||||
id_free (&procgroup->rid_alloc, resource->rid);
|
||||
rbtree_delete (&procgroup->resource_tree, &resource->resource_tree_link);
|
||||
|
||||
spin_unlock (&resource->lock);
|
||||
spin_unlock (&procgroup->lock);
|
||||
spin_unlock (&resource->lock, fr);
|
||||
spin_unlock (&procgroup->lock, fpg);
|
||||
|
||||
resource->ops.cleanup (resource, rctx);
|
||||
free (resource);
|
||||
|
||||
@@ -11,25 +11,27 @@
|
||||
#include <sys/spin_lock.h>
|
||||
|
||||
int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct reschedule_ctx* rctx) {
|
||||
uint64_t lockflags, struct reschedule_ctx* rctx) {
|
||||
uint64_t fc, fp, fsq;
|
||||
|
||||
struct cpu* cpu = proc->cpu;
|
||||
|
||||
struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry));
|
||||
if (!sq_entry) {
|
||||
if (resource_lock != NULL)
|
||||
spin_unlock (resource_lock);
|
||||
spin_unlock (resource_lock, lockflags);
|
||||
return -ST_OOM_ERROR;
|
||||
}
|
||||
|
||||
sq_entry->proc = proc;
|
||||
sq_entry->sq = sq;
|
||||
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&sq->lock);
|
||||
spin_lock (&cpu->lock, &fc);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
spin_lock (&sq->lock, &fsq);
|
||||
|
||||
if (resource_lock != NULL)
|
||||
spin_unlock (resource_lock);
|
||||
spin_unlock (resource_lock, lockflags);
|
||||
|
||||
proc->state = PROC_SUSPENDED;
|
||||
|
||||
@@ -48,9 +50,9 @@ int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_
|
||||
proc->cpu = NULL;
|
||||
int state = proc->state;
|
||||
|
||||
spin_unlock (&sq->lock);
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&sq->lock, fsq);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&cpu->lock, fc);
|
||||
|
||||
rctx_insert_cpu (rctx, cpu);
|
||||
|
||||
@@ -59,12 +61,14 @@ int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_
|
||||
|
||||
int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
struct reschedule_ctx* rctx) {
|
||||
uint64_t fc, fp, fsq;
|
||||
|
||||
struct cpu* cpu = cpu_find_lightest ();
|
||||
struct proc_suspension_q* sq = sq_entry->sq;
|
||||
|
||||
spin_lock (&cpu->lock);
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&sq->lock);
|
||||
spin_lock (&cpu->lock, &fc);
|
||||
spin_lock (&proc->lock, &fp);
|
||||
spin_lock (&sq->lock, &fsq);
|
||||
|
||||
/* remove from sq's list */
|
||||
list_remove (sq->proc_list, &sq_entry->sq_link);
|
||||
@@ -82,9 +86,9 @@ int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
|
||||
int state = proc->state;
|
||||
|
||||
spin_unlock (&sq->lock);
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&sq->lock, fsq);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
spin_unlock (&cpu->lock, fc);
|
||||
|
||||
free (sq_entry);
|
||||
|
||||
@@ -94,7 +98,9 @@ int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
}
|
||||
|
||||
void proc_sqs_cleanup (struct proc* proc) {
|
||||
spin_lock (&proc->lock);
|
||||
uint64_t fsq, fp;
|
||||
|
||||
spin_lock (&proc->lock, &fp);
|
||||
|
||||
/* clean suspension queue entries */
|
||||
struct list_node_link *sq_link, *sq_link_tmp;
|
||||
@@ -102,7 +108,7 @@ void proc_sqs_cleanup (struct proc* proc) {
|
||||
struct proc_sq_entry* sq_entry = list_entry (sq_link, struct proc_sq_entry, proc_link);
|
||||
struct proc_suspension_q* sq = sq_entry->sq;
|
||||
|
||||
spin_lock (&sq->lock);
|
||||
spin_lock (&sq->lock, &fsq);
|
||||
|
||||
/* remove from sq's list */
|
||||
list_remove (sq->proc_list, &sq_entry->sq_link);
|
||||
@@ -110,10 +116,10 @@ void proc_sqs_cleanup (struct proc* proc) {
|
||||
/* remove from proc's list */
|
||||
list_remove (proc->sq_entries, &sq_entry->proc_link);
|
||||
|
||||
spin_unlock (&sq->lock);
|
||||
spin_unlock (&sq->lock, fsq);
|
||||
|
||||
free (sq_entry);
|
||||
}
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&proc->lock, fp);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ struct proc_sq_entry {
|
||||
void proc_sqs_cleanup (struct proc* proc);
|
||||
|
||||
int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct reschedule_ctx* rctx);
|
||||
uint64_t lockflags, struct reschedule_ctx* rctx);
|
||||
|
||||
int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user