Files
DragonOS/kernel/src/time/sleep.c
login 2813126e31 新增rust ffi (#77)
* 引入cargo

* 取消对Cargo.lock的跟踪

* 解决vscode报错问题

* new: rust的代码能够调用c语言的printk_color

* 1、将原本run.sh的工作拆解,变为几个不同的make命令
2、在docker镜像中编译rust

* 更改workflow

* update workflow

* new: 解决workflow无法通过编译的问题
2022-11-11 15:35:37 +08:00

87 lines
1.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "sleep.h"
#include <common/errno.h>
#include <time/timer.h>
#include <process/process.h>
#include <sched/sched.h>
#include <mm/slab.h>
#include <common/cpu.h>
#include <common/glib.h>
/**
* @brief nanosleep定时事件到期后唤醒指定的进程
*
* @param pcb 待唤醒的进程的pcb
*/
void nanosleep_handler(void *pcb)
{
process_wakeup((struct process_control_block *)pcb);
}
/**
* @brief 休眠指定时间
*
* @param rqtp 指定休眠的时间
* @param rmtp 返回的剩余休眠时间
* @return int
*/
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
if (rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000)
return -EINVAL;
// 对于小于500us的时间使用spin/rdtsc来进行定时
if (rqtp->tv_nsec < 500000)
{
uint64_t expired_tsc = rdtsc() + (((uint64_t)rqtp->tv_nsec) * Cpu_tsc_freq) / 1000000000;
while (rdtsc() < expired_tsc)
;
if (rmtp != NULL)
{
rmtp->tv_nsec = 0;
rmtp->tv_sec = 0;
}
return 0;
}
// 增加定时任务
struct timer_func_list_t *sleep_task = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
memset(sleep_task, 0, sizeof(struct timer_func_list_t));
timer_func_init_us(sleep_task, &nanosleep_handler, (void *)current_pcb, rqtp->tv_nsec / 1000);
timer_func_add(sleep_task);
current_pcb->state = PROC_INTERRUPTIBLE;
current_pcb->flags |= PF_NEED_SCHED;
sched();
// todo: 增加信号唤醒的功能后设置rmtp
if (rmtp != NULL)
{
rmtp->tv_nsec = 0;
rmtp->tv_sec = 0;
}
return 0;
}
/**
* @brief 睡眠指定时间
*
* @param usec 微秒
* @return int
*/
int usleep(useconds_t usec)
{
struct timespec ts = {
tv_sec : (long int)(usec / 1000000),
tv_nsec : (long int)(usec % 1000000) * 1000UL
};
return nanosleep(&ts, NULL);
}