Redesign reschedule points, allow one operation to reschedule many cpus at once
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m12s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m12s
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
#include <libk/list.h>
|
||||
#include <libk/minmax.h>
|
||||
#include <libk/std.h>
|
||||
#include <libk/string.h>
|
||||
#include <mm/liballoc.h>
|
||||
@@ -8,9 +10,8 @@
|
||||
#include <sys/debug.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** reschedule_cpu) {
|
||||
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx) {
|
||||
struct proc_mail* mail = &resource->u.mail;
|
||||
bool reschedule = PROC_NO_RESCHEDULE;
|
||||
|
||||
spin_lock (&mail->resource->lock);
|
||||
|
||||
@@ -29,7 +30,7 @@ bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** re
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
reschedule = reschedule || proc_sq_resume (suspended_proc, sq_entry, reschedule_cpu);
|
||||
proc_sq_resume (suspended_proc, sq_entry, rctx);
|
||||
|
||||
spin_lock (&mail->resource->lock);
|
||||
spin_lock (&mail->send_sq.lock);
|
||||
@@ -38,13 +39,18 @@ bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** re
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
|
||||
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);
|
||||
|
||||
/* mail full */
|
||||
if (mail->pending_mesg != NULL) {
|
||||
proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock (&mail->recv_sq.lock);
|
||||
|
||||
/* if receiver available, hand off directly */
|
||||
@@ -57,40 +63,33 @@ bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** res
|
||||
spin_unlock (&mail->recv_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
spin_lock (&proc->lock);
|
||||
spin_lock (&resumed_proc->lock);
|
||||
|
||||
if (resumed_proc->mail_recv_buffer != NULL) {
|
||||
size_t copy_size =
|
||||
(data_size < resumed_proc->mail_recv_size) ? data_size : resumed_proc->mail_recv_size;
|
||||
size_t copy_size = min (data_size, resumed_proc->mail_recv_size);
|
||||
memcpy (resumed_proc->mail_recv_buffer, data, copy_size);
|
||||
|
||||
resumed_proc->mail_recv_buffer = NULL;
|
||||
resumed_proc->mail_recv_size = 0;
|
||||
}
|
||||
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&resumed_proc->lock);
|
||||
|
||||
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock (&mail->recv_sq.lock);
|
||||
|
||||
/* mail full */
|
||||
if (mail->pending_mesg != NULL) {
|
||||
return proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, reschedule_cpu);
|
||||
}
|
||||
|
||||
/* mail is empty and nobody is waiting */
|
||||
mail->pending_mesg = malloc (data_size);
|
||||
memcpy (mail->pending_mesg, data, data_size);
|
||||
mail->pending_mesg_size = data_size;
|
||||
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
return PROC_NO_RESCHEDULE;
|
||||
}
|
||||
|
||||
bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
|
||||
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);
|
||||
proc->mail_recv_buffer = recv_buffer;
|
||||
@@ -118,15 +117,16 @@ bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu**
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_unlock (&mail->send_sq.lock);
|
||||
spin_unlock (&mail->resource->lock);
|
||||
|
||||
return PROC_NO_RESCHEDULE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* nothing to receive */
|
||||
return proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, reschedule_cpu);
|
||||
proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, rctx);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#ifndef _KERNEL_PROC_MAIL_H
|
||||
#define _KERNEL_PROC_MAIL_H
|
||||
|
||||
#include <libk/list.h>
|
||||
#include <libk/std.h>
|
||||
#include <proc/suspension_q.h>
|
||||
|
||||
struct proc;
|
||||
struct proc_resource;
|
||||
struct cpu;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc_mail {
|
||||
struct proc_resource* resource;
|
||||
@@ -17,10 +19,12 @@ struct proc_mail {
|
||||
size_t pending_mesg_size;
|
||||
};
|
||||
|
||||
bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** reschedule_cpu);
|
||||
bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
|
||||
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx);
|
||||
|
||||
void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
|
||||
void* data, size_t data_size);
|
||||
bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
|
||||
|
||||
void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
|
||||
void* recv_buffer, size_t recv_size);
|
||||
|
||||
#endif // _KERNEL_PROC_MAIL_H
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <sys/smp.h>
|
||||
#include <sys/spin_lock.h>
|
||||
|
||||
void proc_mutexes_cleanup (struct proc* proc) {
|
||||
void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&proc->procgroup->lock);
|
||||
|
||||
struct rb_node_link* rnode;
|
||||
@@ -35,22 +35,19 @@ void proc_mutexes_cleanup (struct proc* proc) {
|
||||
if (resource->u.mutex.owner == proc && resource->u.mutex.locked) {
|
||||
spin_unlock (&resource->lock);
|
||||
|
||||
struct cpu* reschedule_cpu;
|
||||
proc_mutex_unlock (proc, &resource->u.mutex, &reschedule_cpu);
|
||||
proc_mutex_unlock (proc, &resource->u.mutex, rctx);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock (&proc->procgroup->lock);
|
||||
}
|
||||
|
||||
bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** reschedule_cpu) {
|
||||
void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx) {
|
||||
struct proc_mutex* mutex = &resource->u.mutex;
|
||||
|
||||
spin_lock (&mutex->resource->lock);
|
||||
spin_lock (&mutex->suspension_q.lock);
|
||||
|
||||
bool reschedule = PROC_NO_RESCHEDULE;
|
||||
|
||||
while (mutex->suspension_q.proc_list != NULL) {
|
||||
struct list_node_link* node = mutex->suspension_q.proc_list;
|
||||
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
|
||||
@@ -60,7 +57,7 @@ bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** r
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
|
||||
reschedule = reschedule || proc_sq_resume (suspended_proc, sq_entry, reschedule_cpu);
|
||||
proc_sq_resume (suspended_proc, sq_entry, rctx);
|
||||
|
||||
/* reacquire */
|
||||
spin_lock (&mutex->resource->lock);
|
||||
@@ -72,29 +69,27 @@ bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** r
|
||||
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
bool proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu) {
|
||||
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&mutex->resource->lock);
|
||||
|
||||
if (!mutex->locked || mutex->owner == proc) {
|
||||
mutex->locked = true;
|
||||
mutex->owner = proc;
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
return PROC_NO_RESCHEDULE;
|
||||
return;
|
||||
}
|
||||
|
||||
return proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, reschedule_cpu);
|
||||
proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, rctx);
|
||||
}
|
||||
|
||||
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu) {
|
||||
void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&mutex->resource->lock);
|
||||
|
||||
if (mutex->owner != proc) {
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
return PROC_NO_RESCHEDULE;
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock (&mutex->suspension_q.lock);
|
||||
@@ -111,7 +106,8 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu*
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
|
||||
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
|
||||
proc_sq_resume (resumed_proc, sq_entry, rctx);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex->locked = false;
|
||||
@@ -119,6 +115,4 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu*
|
||||
|
||||
spin_unlock (&mutex->suspension_q.lock);
|
||||
spin_unlock (&mutex->resource->lock);
|
||||
|
||||
return PROC_NO_RESCHEDULE;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#ifndef _KERNEL_PROC_MUTEX_H
|
||||
#define _KERNEL_PROC_MUTEX_H
|
||||
|
||||
#include <libk/list.h>
|
||||
#include <libk/std.h>
|
||||
#include <proc/suspension_q.h>
|
||||
|
||||
struct proc;
|
||||
struct proc_resource;
|
||||
struct cpu;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc_mutex {
|
||||
struct proc_resource* resource;
|
||||
@@ -16,9 +18,12 @@ struct proc_mutex {
|
||||
struct proc* owner;
|
||||
};
|
||||
|
||||
bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** reschedule_cpu);
|
||||
bool proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu);
|
||||
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu);
|
||||
void proc_mutexes_cleanup (struct proc* proc);
|
||||
void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx);
|
||||
|
||||
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx);
|
||||
|
||||
void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx);
|
||||
|
||||
void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx);
|
||||
|
||||
#endif // _KERNEL_PROC_MUTEX_H
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <proc/capability.h>
|
||||
#include <proc/proc.h>
|
||||
#include <proc/procgroup.h>
|
||||
#include <proc/reschedule.h>
|
||||
#include <proc/resource.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/debug.h>
|
||||
@@ -160,8 +161,8 @@ struct proc* proc_find_pid (int pid) {
|
||||
return proc;
|
||||
}
|
||||
|
||||
bool proc_register (struct proc* proc, struct cpu** reschedule_cpu) {
|
||||
struct cpu* cpu = *reschedule_cpu != NULL ? *reschedule_cpu : cpu_find_lightest ();
|
||||
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx) {
|
||||
struct cpu* cpu = register_cpu != NULL ? register_cpu : cpu_find_lightest ();
|
||||
|
||||
spin_lock (&proc_tree_lock);
|
||||
spin_lock (&cpu->lock);
|
||||
@@ -180,9 +181,8 @@ bool proc_register (struct proc* proc, struct cpu** reschedule_cpu) {
|
||||
spin_unlock (&cpu->lock);
|
||||
spin_unlock (&proc_tree_lock);
|
||||
|
||||
*reschedule_cpu = cpu;
|
||||
|
||||
return PROC_NEED_RESCHEDULE;
|
||||
if (rctx != NULL)
|
||||
reschedule_list_append (rctx, cpu);
|
||||
}
|
||||
|
||||
/* caller holds cpu->lock */
|
||||
@@ -214,7 +214,7 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void proc_reap (void) {
|
||||
static void proc_reap (struct reschedule_ctx* rctx) {
|
||||
struct proc* proc = NULL;
|
||||
struct list_node_link* reap_list = NULL;
|
||||
|
||||
@@ -246,15 +246,16 @@ static void proc_reap (void) {
|
||||
|
||||
list_remove (reap_list, &proc->reap_link);
|
||||
DEBUG ("cleanup PID %d\n", proc->pid);
|
||||
proc_cleanup (proc);
|
||||
proc_cleanup (proc, rctx);
|
||||
}
|
||||
}
|
||||
|
||||
void proc_sched (void) {
|
||||
int s_cycles = atomic_fetch_add (&sched_cycles, 1);
|
||||
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
|
||||
|
||||
if (s_cycles % SCHED_REAP_FREQ == 0)
|
||||
proc_reap ();
|
||||
proc_reap (&rctx);
|
||||
|
||||
struct proc* next = NULL;
|
||||
struct cpu* cpu = thiscpu;
|
||||
@@ -275,7 +276,7 @@ void proc_sched (void) {
|
||||
}
|
||||
}
|
||||
|
||||
bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu) {
|
||||
void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
|
||||
spin_lock (&proc->lock);
|
||||
struct cpu* cpu = proc->cpu;
|
||||
spin_unlock (&proc->lock);
|
||||
@@ -294,17 +295,14 @@ bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu) {
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
|
||||
reschedule_list_append (rctx, cpu);
|
||||
|
||||
DEBUG ("killed PID %d\n", proc->pid);
|
||||
|
||||
*reschedule_cpu = cpu;
|
||||
|
||||
return PROC_NEED_RESCHEDULE;
|
||||
}
|
||||
|
||||
static bool proc_irq_sched (struct cpu** reschedule_cpu, void* arg, void* regs) {
|
||||
(void)arg, (void)regs, (void)reschedule_cpu;
|
||||
static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) {
|
||||
(void)arg, (void)regs;
|
||||
proc_sched ();
|
||||
return PROC_NO_RESCHEDULE;
|
||||
}
|
||||
|
||||
void proc_init (void) {
|
||||
@@ -314,13 +312,11 @@ void proc_init (void) {
|
||||
#endif
|
||||
|
||||
struct proc* spin_proc = proc_from_file (NULL, "ramdisk", "/spin");
|
||||
struct cpu* spin_cpu = thiscpu;
|
||||
proc_register (spin_proc, &spin_cpu);
|
||||
proc_register (spin_proc, thiscpu, NULL);
|
||||
|
||||
struct proc* init = proc_from_file (NULL, "ramdisk", "/init");
|
||||
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
|
||||
struct cpu* init_cpu = thiscpu;
|
||||
proc_register (init, &init_cpu);
|
||||
proc_register (init, thiscpu, NULL);
|
||||
|
||||
spin_lock (&spin_proc->cpu->lock);
|
||||
do_sched (spin_proc, &spin_proc->cpu->lock);
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
#include <amd64/proc.h> /* USTACK_SIZE */
|
||||
#endif
|
||||
|
||||
#define PROC_NEED_RESCHEDULE true
|
||||
#define PROC_NO_RESCHEDULE false
|
||||
|
||||
/* process states */
|
||||
#define PROC_READY 0
|
||||
#define PROC_DEAD 1
|
||||
@@ -29,6 +26,7 @@
|
||||
#define PROC_USTK_PREALLOC (1 << 0)
|
||||
|
||||
struct cpu;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc {
|
||||
int pid;
|
||||
@@ -50,11 +48,17 @@ struct proc {
|
||||
};
|
||||
|
||||
void proc_sched (void);
|
||||
bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu);
|
||||
|
||||
void proc_kill (struct proc* proc, struct reschedule_ctx* rctx);
|
||||
|
||||
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
|
||||
bool proc_register (struct proc* proc, struct cpu** reschedule_cpu);
|
||||
|
||||
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx);
|
||||
|
||||
struct proc* proc_find_pid (int pid);
|
||||
|
||||
struct proc* proc_from_file (struct procgroup* procgroup, const char* mountpoint, const char* path);
|
||||
|
||||
void proc_init (void);
|
||||
|
||||
#endif // _KERNEL_PROC_PROC_H
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mm/pmm.h>
|
||||
#include <proc/proc.h>
|
||||
#include <proc/procgroup.h>
|
||||
#include <proc/reschedule.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/mm.h>
|
||||
@@ -176,7 +177,8 @@ void procgroup_attach (struct procgroup* procgroup, struct proc* proc) {
|
||||
spin_unlock (&procgroup->lock);
|
||||
}
|
||||
|
||||
void procgroup_detach (struct procgroup* procgroup, struct proc* proc) {
|
||||
void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
|
||||
struct reschedule_ctx* rctx) {
|
||||
spin_lock (&procgroup->lock);
|
||||
spin_lock (&proc->lock);
|
||||
|
||||
@@ -207,8 +209,7 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc) {
|
||||
|
||||
rnode = next;
|
||||
|
||||
struct cpu* reschedule_cpu;
|
||||
proc_delete_resource (resource, &reschedule_cpu);
|
||||
proc_delete_resource (resource, rctx);
|
||||
}
|
||||
|
||||
/* unlock VFS owned mountpoints */
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <sys/procgroup.h>
|
||||
|
||||
struct proc;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc_mapping {
|
||||
struct list_node_link proc_mappings_link;
|
||||
@@ -35,11 +36,16 @@ struct procgroup {
|
||||
};
|
||||
|
||||
struct procgroup* procgroup_create (void);
|
||||
|
||||
void procgroup_attach (struct procgroup* procgroup, struct proc* proc);
|
||||
void procgroup_detach (struct procgroup* procgroup, struct proc* proc);
|
||||
|
||||
void procgroup_detach (struct procgroup* procgroup, struct proc* proc, struct reschedule_ctx* rctx);
|
||||
|
||||
uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pages, uint32_t flags,
|
||||
uintptr_t* out_paddr);
|
||||
|
||||
bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t pages);
|
||||
|
||||
struct procgroup* procgroup_find (int pgid);
|
||||
|
||||
#endif // _KERNEL_PROC_PROCGROUP_H
|
||||
|
||||
32
kernel/proc/reschedule.c
Normal file
32
kernel/proc/reschedule.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <libk/list.h>
|
||||
#include <mm/liballoc.h>
|
||||
#include <proc/reschedule.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
void reschedule_list_append (struct reschedule_ctx* rctx, struct cpu* cpu) {
|
||||
spin_lock (&rctx->lock);
|
||||
|
||||
struct list_node_link *node, *tmp;
|
||||
list_foreach (rctx->entries, node, tmp) {
|
||||
struct reschedule_entry* entry = list_entry (node, struct reschedule_entry, link);
|
||||
|
||||
if (entry->cpu == cpu) {
|
||||
spin_unlock (&rctx->lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct reschedule_entry* entry = malloc (sizeof (*entry));
|
||||
|
||||
if (entry == NULL) {
|
||||
spin_unlock (&rctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
entry->cpu = cpu;
|
||||
|
||||
list_append (rctx->entries, &entry->link);
|
||||
|
||||
spin_unlock (&rctx->lock);
|
||||
}
|
||||
20
kernel/proc/reschedule.h
Normal file
20
kernel/proc/reschedule.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _KERNEL_PROC_RESCHEDULE_H
|
||||
#define _KERNEL_PROC_RESCHEDULE_H
|
||||
|
||||
#include <libk/list.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
struct reschedule_entry {
|
||||
struct cpu* cpu;
|
||||
struct list_node_link link;
|
||||
};
|
||||
|
||||
struct reschedule_ctx {
|
||||
struct list_node_link* entries;
|
||||
spin_lock_t lock;
|
||||
};
|
||||
|
||||
void reschedule_list_append (struct reschedule_ctx* rctx, struct cpu* cpu);
|
||||
|
||||
#endif // _KERNEL_PROC_RESCHEDULE_H
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <proc/mutex.h>
|
||||
#include <proc/proc.h>
|
||||
#include <proc/procgroup.h>
|
||||
#include <proc/reschedule.h>
|
||||
#include <proc/resource.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/debug.h>
|
||||
@@ -76,9 +77,7 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, in
|
||||
return resource;
|
||||
}
|
||||
|
||||
bool proc_delete_resource (struct proc_resource* resource, struct cpu** reschedule_cpu) {
|
||||
bool reschedule = resource->ops.cleanup (resource, reschedule_cpu);
|
||||
void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx) {
|
||||
resource->ops.cleanup (resource, rctx);
|
||||
free (resource);
|
||||
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
struct proc;
|
||||
struct procgroup;
|
||||
struct cpu;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc_resource {
|
||||
int type;
|
||||
@@ -25,13 +26,16 @@ struct proc_resource {
|
||||
struct proc_mail mail;
|
||||
} u;
|
||||
struct {
|
||||
bool (*cleanup) (struct proc_resource* resource, struct cpu** reschedule_cpu);
|
||||
void (*cleanup) (struct proc_resource* resource, struct reschedule_ctx* rctx);
|
||||
} ops;
|
||||
};
|
||||
|
||||
struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid);
|
||||
|
||||
struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup, int rid);
|
||||
|
||||
struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, int rid);
|
||||
bool proc_delete_resource (struct proc_resource* resource, struct cpu** reschedule_cpu);
|
||||
|
||||
void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx);
|
||||
|
||||
#endif // _KERNEL_PROC_RESOURCE_H
|
||||
|
||||
@@ -3,11 +3,13 @@ c += proc/proc.c \
|
||||
proc/mutex.c \
|
||||
proc/procgroup.c \
|
||||
proc/suspension_q.c \
|
||||
proc/mail.c
|
||||
proc/mail.c \
|
||||
proc/reschedule.c
|
||||
|
||||
o += proc/proc.o \
|
||||
proc/resource.o \
|
||||
proc/mutex.o \
|
||||
proc/procgroup.o \
|
||||
proc/suspension_q.o \
|
||||
proc/mail.o
|
||||
proc/mail.o \
|
||||
proc/reschedule.o
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
#include <libk/std.h>
|
||||
#include <mm/liballoc.h>
|
||||
#include <proc/proc.h>
|
||||
#include <proc/reschedule.h>
|
||||
#include <proc/resource.h>
|
||||
#include <proc/suspension_q.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/spin_lock.h>
|
||||
|
||||
bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct cpu** reschedule_cpu) {
|
||||
void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct reschedule_ctx* rctx) {
|
||||
struct cpu* cpu = proc->cpu;
|
||||
|
||||
struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry));
|
||||
if (!sq_entry) {
|
||||
spin_unlock (resource_lock);
|
||||
return PROC_NO_RESCHEDULE;
|
||||
return;
|
||||
}
|
||||
|
||||
sq_entry->proc = proc;
|
||||
@@ -47,13 +48,11 @@ bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
|
||||
spin_unlock (&proc->lock);
|
||||
spin_unlock (&cpu->lock);
|
||||
|
||||
*reschedule_cpu = cpu;
|
||||
|
||||
return PROC_NEED_RESCHEDULE;
|
||||
reschedule_list_append (rctx, cpu);
|
||||
}
|
||||
|
||||
bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
struct cpu** reschedule_cpu) {
|
||||
void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
struct reschedule_ctx* rctx) {
|
||||
struct cpu* cpu = cpu_find_lightest ();
|
||||
struct proc_suspension_q* sq = sq_entry->sq;
|
||||
|
||||
@@ -81,9 +80,7 @@ bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
|
||||
free (sq_entry);
|
||||
|
||||
*reschedule_cpu = cpu;
|
||||
|
||||
return PROC_NEED_RESCHEDULE;
|
||||
reschedule_list_append (rctx, cpu);
|
||||
}
|
||||
|
||||
void proc_sqs_cleanup (struct proc* proc) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
struct proc;
|
||||
struct cpu;
|
||||
struct reschedule_ctx;
|
||||
|
||||
struct proc_suspension_q {
|
||||
struct list_node_link* proc_list;
|
||||
@@ -20,9 +21,11 @@ struct proc_sq_entry {
|
||||
};
|
||||
|
||||
void proc_sqs_cleanup (struct proc* proc);
|
||||
bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct cpu** reschedule_cpu);
|
||||
bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
struct cpu** reschedule_cpu);
|
||||
|
||||
void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
|
||||
struct reschedule_ctx* rctx);
|
||||
|
||||
void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
|
||||
struct reschedule_ctx* rctx);
|
||||
|
||||
#endif // _KERNEL_PROC_SUSPENTION_Q_H
|
||||
|
||||
Reference in New Issue
Block a user