diff --git a/kernel/process/atomic.h b/kernel/process/atomic.h new file mode 100644 index 00000000..e663e8c9 --- /dev/null +++ b/kernel/process/atomic.h @@ -0,0 +1,99 @@ +/** + * @file atomic.h + * @author fslongjin (longjin@RinGoTek.cn) + * @brief 原子变量 + * @version 0.1 + * @date 2022-04-12 + * + * @copyright Copyright (c) 2022 + * + */ +#pragma once + +#define atomic_read(atomic) ((atomic)->value) // 读取原子变量 +#define atomic_set(atomic,val) (((atomic)->value) = (val)) // 设置原子变量的初始值 + +typedef struct +{ + volatile long value; +} atomic_t; + +/** + * @brief 原子变量增加值 + * + * @param ato 原子变量对象 + * @param val 要增加的值 + */ +static inline void atomic_add(atomic_t *ato, long val) +{ + asm volatile("lock addq %1, %0 \n\t" + : "=m"(ato->value) + : "m"(val) + : "memory"); +} + +/** + * @brief 原子变量减少值 + * + * @param ato 原子变量对象 + * @param val 要减少的值 + */ +static inline void atomic_sub(atomic_t *ato, long val) +{ + asm volatile("lock subq %1, %0 \n\t" + : "=m"(ato->value) + : "m"(val) + : "memory"); +} + +/** + * @brief 原子变量自增 + * + * @param ato 原子变量对象 + */ +static inline void atomic_inc(atomic_t *ato) +{ + asm volatile("lock incq %0 \n\t" + : "=m"(ato->value) + : "m"(ato->value) + : "memory"); +} + +/** + * @brief 原子变量自减 + * + * @param ato 原子变量对象 + */ +static inline void atomic_dec(atomic_t *ato) +{ + asm volatile("lock decq %0 \n\t" + : "=m"(ato->value) + : "m"(ato->value) + : "memory"); +} + +/** + * @brief 设置原子变量的mask + * + * @param ato 原子变量对象 + */ +static inline void atomic_set_mask(atomic_t *ato, long mask) +{ + __asm__ __volatile__("lock orq %1, %0 \n\t" + : "=m"(ato->value) + : "r"(mask) + : "memory"); +} + +/** + * @brief 清除原子变量的mask + * + * @param ato 原子变量对象 + */ +static inline void atomic_clear_mask(atomic_t *ato, long mask) +{ + __asm__ __volatile__("lock andq %1, %0 \n\t" + : "=m"(ato->value) + : "r"(mask) + : "memory"); +} diff --git a/kernel/process/semaphore.h b/kernel/process/semaphore.h new file mode 100644 index 00000000..47835049 --- /dev/null +++ b/kernel/process/semaphore.h @@ -0,0 +1,101 @@ +/** + * @file semaphore.h + * @author fslngjin (lonjin@RinGoTek.cn) + * @brief 信号量 + * @version 0.1 + * @date 2022-04-12 + * + * @copyright Copyright (c) 2022 + * + */ + +#pragma once +#include + +#include +#include + +/** + * @brief 信号量的等待队列 + * + */ +typedef struct +{ + struct List wait_list; + struct process_control_block *pcb; +} wait_queue_node_t; + +/** + * @brief 初始化信号量的等待队列 + * + * @param wait_queue 等待队列 + * @param pcb pcb + */ +void wait_queue_init(wait_queue_node_t *wait_queue, struct process_control_block *pcb) +{ + list_init(&wait_queue->wait_list); + wait_queue->pcb = pcb; +} + +/** + * @brief 信号量的结构体 + * + */ +typedef struct +{ + atomic_t counter; + wait_queue_node_t wait_queue; +} semaphore_t; + +/** + * @brief 初始化信号量 + * + * @param sema 信号量对象 + * @param count 信号量的初始值 + */ +void semaphore_init(semaphore_t *sema, ul count) +{ + atomic_set(&sema->counter, count); + wait_queue_init(&sema->wait_queue, NULL); +} + +/** + * @brief 信号量down + * + * @param sema + */ +void semaphore_down(semaphore_t *sema) +{ + if (atomic_read(&sema->counter) > 0) // 信号量大于0,资源充足 + atomic_dec(&sema->counter); + else // 资源不足,进程休眠 + { + // 将当前进程加入信号量的等待队列 + wait_queue_node_t wait; + wait_queue_init(&wait, current_pcb); + + current_pcb->state = PROC_UNINTERRUPTIBLE; + + list_append(&sema->wait_queue.wait_list, &wait.wait_list); + + // 执行调度 + sched_cfs(); + } +} + +void semaphore_up(semaphore_t *sema) +{ + if (list_empty(&sema->wait_queue.wait_list)) // 没有进程在等待资源 + { + atomic_inc(&sema->counter); + } + else // 有进程在等待资源,唤醒进程 + { + + wait_queue_node_t *wq = container_of(list_next(&sema->wait_queue.wait_list), wait_queue_node_t, wait_list); + list_del(&wq->wait_list); + + wq->pcb->state = PROC_RUNNING; + sched_cfs_enqueue(wq->pcb); + } +} \ No newline at end of file diff --git a/kernel/process/spinlock.h b/kernel/process/spinlock.h index c36caf12..68d044a5 100644 --- a/kernel/process/spinlock.h +++ b/kernel/process/spinlock.h @@ -8,6 +8,7 @@ * @copyright Copyright (c) 2022 * */ +#pragma once #include "../common/glib.h" /** diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 81e9a091..1e53c61a 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -77,10 +77,10 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg ul sys_printf(struct pt_regs *regs) { - // if(regs->r9 == 0 &®s->r10 == 0) - // printk((char*)regs->r8); - // else printk_color(regs->r9, regs->r10, (char*)regs->r8); - printk_color(BLACK, WHITE, (char *)regs->r8); + if(regs->r9 == 0 &®s->r10 == 0) + printk((char*)regs->r8); + else printk_color(regs->r9, regs->r10, (char*)regs->r8); + // printk_color(BLACK, WHITE, (char *)regs->r8); return 0; }