Spinlock save cpu flags

This commit is contained in:
2026-03-12 22:48:34 +01:00
parent 19793e9126
commit 4760818118
50 changed files with 704 additions and 461 deletions

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);