实现设置pcb名字和vsnprintf (#72)

* 实现pcb设置名字

* 实现设置pcb名字,实现vsnprintf

* 修改set_pcb_name和va_end

* bugfix: 修正一些小问题

Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
houmkh 2022-10-31 20:46:20 +08:00 committed by GitHub
parent 8a080f3cce
commit 8e3f5674f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 174 additions and 47 deletions

View File

@ -5,6 +5,22 @@
#include <common/err.h> #include <common/err.h>
#include <process/process.h> #include <process/process.h>
/**
* @brief kthread信息
* pcb的worker_private中
*/
struct kthread_info_t
{
uint64_t flags;
uint32_t cpu;
int result;
int (*thread_fn)(void *);
void *data;
// todo: 将这里改为completion机制
bool exited; // 是否已退出
char *full_name; // 内核线程的名称
};
struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data), struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data),
void *data, void *data,
int node, int node,
@ -74,4 +90,5 @@ int kthread_mechanism_init();
* @param pcb pcb * @param pcb pcb
* @return bool * @return bool
*/ */
bool kthread_set_worker_private(struct process_control_block *pcb); bool kthread_set_worker_private(struct process_control_block *pcb);

View File

@ -38,6 +38,7 @@
extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap8*16大小 ps:位于font.h中 extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap8*16大小 ps:位于font.h中
/** /**
* @brief fmt和args中的内容进行格式化buf中 * @brief fmt和args中的内容进行格式化buf中
* *
@ -48,6 +49,17 @@ extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap8*16大
*/ */
int vsprintf(char *buf, const char *fmt, va_list args); int vsprintf(char *buf, const char *fmt, va_list args);
/**
* @brief fmt和args中的内容进行格式化buf_size-1buf中
*
* @param buf buf_size
* @param fmt
* @param buf_size
* @param args
* @return
*/
int vsnprintf(char *buf, const char *fmt, int buf_size, va_list args);
/** /**
* @brief * @brief
* *

View File

@ -796,12 +796,12 @@ int do_unlink_at(int dfd, const char *pathname, bool from_userland)
struct vfs_index_node_t *p_inode = dentry->parent->dir_inode; struct vfs_index_node_t *p_inode = dentry->parent->dir_inode;
// 对父inode加锁 // 对父inode加锁
spin_lock(&p_inode); spin_lock(&p_inode->lockref.lock);
retval = vfs_unlink(NULL, dentry->parent->dir_inode, dentry, NULL); retval = vfs_unlink(NULL, dentry->parent->dir_inode, dentry, NULL);
spin_lock(&dentry->lockref.lock); spin_lock(&dentry->lockref.lock);
retval = vfs_dentry_put(dentry); retval = vfs_dentry_put(dentry);
spin_unlock(&p_inode); spin_unlock(&p_inode->lockref.lock);
if (IS_ERR(retval)) if (IS_ERR(retval))
kwarn("In do_unlink_at: dentry put failed; retval=%d", retval); kwarn("In do_unlink_at: dentry put failed; retval=%d", retval);

View File

@ -42,18 +42,22 @@ static int skip_and_atoi(const char **s)
} }
/** /**
* fmt和args中的内容进行格式化buf中 * @brief fmt和args中的内容进行格式化buf_size为-1buf中
* buf_size-1buf_size的buf数组中
*
* @param buf * @param buf
* @param fmt * @param fmt
* @param args * @param args
* @param buf_size buf_size为-1buf的大小buf大小为buf_size
* @return * @return
*/ */
int vsprintf(char *buf, const char *fmt, va_list args) static int __do_vsprintf(char *buf, const char *fmt, int buf_size, va_list args)
{ {
// 当需要输出的字符串的指针为空时,使用该字符填充目标字符串的指针 // 当需要输出的字符串的指针为空时,使用该字符填充目标字符串的指针
static const char __end_zero_char = '\0'; static const char __end_zero_char = '\0';
char *str = NULL, *s = NULL; char *str = NULL, *s = NULL, *end = NULL;
str = buf; str = buf;
@ -63,6 +67,10 @@ int vsprintf(char *buf, const char *fmt, va_list args)
int qualifier; //数据显示的类型 int qualifier; //数据显示的类型
int len; int len;
if (buf_size != -1)
{
end = buf + buf_size;
}
//开始解析字符串 //开始解析字符串
for (; *fmt; ++fmt) for (; *fmt; ++fmt)
{ {
@ -324,12 +332,54 @@ int vsprintf(char *buf, const char *fmt, va_list args)
break; break;
} }
} }
*str = '\0'; //实现vsnprintf 的功能
if (buf_size > 0)
{
if (str < end)
{
*str = '\0';
}
else
{
*(end-1) = '\0';
}
return buf_size;
}
else
{
*str = '\0';
}
//返回缓冲区已有字符串的长度。 //返回缓冲区已有字符串的长度。
return str - buf; return str - buf;
} }
/**
* fmt和args中的内容进行格式化buf中
* @param buf
* @param fmt
* @param args
* @return
*/
int vsprintf(char *buf, const char *fmt, va_list args)
{
return __do_vsprintf(buf, fmt, -1, args);
}
/**
* @brief fmt和args中的内容进行格式化buf_size-1buf中
*
* @param buf buf_size
* @param fmt
* @param buf_size
* @param args
* @return
*/
int vsnprintf(char *buf, const char *fmt, int buf_size, va_list args)
{
return __do_vsprintf(buf, fmt, buf_size, args);
}
static char *write_num(char *str, ul num, int base, int field_width, int precision, int flags) static char *write_num(char *str, ul num, int base, int field_width, int precision, int flags)
{ {
/** /**
@ -477,8 +527,8 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
if (sign) if (sign)
--field_width; --field_width;
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度 int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
uint64_t num_z = (uint64_t)(num); // 获取整数部分 uint64_t num_z = (uint64_t)(num); // 获取整数部分
uint64_t num_decimal = (uint64_t)(round(1.0 * (num - num_z) * pow(10, precision))); // 获取小数部分 uint64_t num_decimal = (uint64_t)(round(1.0 * (num - num_z) * pow(10, precision))); // 获取小数部分
if (num == 0 || num_z == 0) if (num == 0 || num_z == 0)

View File

@ -1,8 +1,8 @@
#include <common/kthread.h>
#include <common/glib.h> #include <common/glib.h>
#include <common/kthread.h>
#include <common/spinlock.h> #include <common/spinlock.h>
#include <sched/sched.h>
#include <debug/bug.h> #include <debug/bug.h>
#include <sched/sched.h>
#include <time/sleep.h> #include <time/sleep.h>
static spinlock_t __kthread_create_lock; // kthread创建过程的锁 static spinlock_t __kthread_create_lock; // kthread创建过程的锁
@ -28,28 +28,13 @@ struct kthread_create_info_t
void *data; void *data;
int node; int node;
// kthreadd守护进程传递给kthread_create的结果, 成功则返回PCB不成功则该值为负数错误码。若该值为NULL意味着创建过程尚未完成 // kthreadd守护进程传递给kthread_create的结果,
// 成功则返回PCB不成功则该值为负数错误码。若该值为NULL意味着创建过程尚未完成
struct process_control_block *result; struct process_control_block *result;
struct List list; struct List list;
}; };
/**
* @brief kthread信息
* pcb的worker_private中
*/
struct kthread_info_t
{
uint64_t flags;
uint32_t cpu;
int result;
int (*thread_fn)(void *);
void *data;
// todo: 将这里改为completion机制
bool exited; // 是否已退出
char *full_name; // 内核线程的名称
};
/** /**
* @brief pcb中的kthread结构体 * @brief pcb中的kthread结构体
* *
@ -62,8 +47,7 @@ static inline struct kthread_info_t *to_kthread(struct process_control_block *pc
return pcb->worker_private; return pcb->worker_private;
} }
static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(void *data), void *data, static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(void *data), void *data, int node,
int node,
const char name_fmt[], va_list args) const char name_fmt[], va_list args)
{ {
struct process_control_block *pcb = NULL; struct process_control_block *pcb = NULL;
@ -96,6 +80,22 @@ static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(v
if (!IS_ERR(create->result)) if (!IS_ERR(create->result))
{ {
// todo: 为内核线程设置名字 // todo: 为内核线程设置名字
char pcb_name[PCB_NAME_LEN];
va_list get_args;
va_copy(get_args, args);
//获取到字符串的前16字节
int len = vsnprintf(pcb_name, name_fmt, PCB_NAME_LEN, get_args);
if (len >= PCB_NAME_LEN)
{
//名字过大 放到full_name字段中
struct kthread_info_t *kthread = to_kthread(pcb);
char *full_name = kzalloc(1024, __GFP_ZERO);
vsprintf(full_name, name_fmt, get_args);
kthread->full_name = full_name;
}
//将前16Bytes放到pcb的name字段
process_set_pcb_name(pcb, pcb_name);
va_end(get_args);
} }
kfree(create); kfree(create);
@ -131,8 +131,7 @@ void kthread_exit(long result)
* 线thread_fn函数data作为参数传入 * 线thread_fn函数data作为参数传入
* 线kthread_should_stop为真时返回 * 线kthread_should_stop为真时返回
*/ */
struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data), void *data, struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data), void *data, int node,
int node,
const char name_fmt[], ...) const char name_fmt[], ...)
{ {
struct process_control_block *pcb; struct process_control_block *pcb;
@ -171,7 +170,7 @@ static int kthread(void *_create)
// 将当前pcb返回给创建者 // 将当前pcb返回给创建者
create->result = current_pcb; create->result = current_pcb;
current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态 current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态
// 发起调度使得当前内核线程休眠。直到创建者通过process_wakeup将当前内核线程唤醒 // 发起调度使得当前内核线程休眠。直到创建者通过process_wakeup将当前内核线程唤醒
sched(); sched();
@ -221,7 +220,8 @@ int kthreadd(void *unused)
{ {
// 从链表中取出第一个要创建的内核线程任务 // 从链表中取出第一个要创建的内核线程任务
struct kthread_create_info_t *create = container_of(kthread_create_list.next, struct kthread_create_info_t, list); struct kthread_create_info_t *create =
container_of(kthread_create_list.next, struct kthread_create_info_t, list);
list_del_init(&create->list); list_del_init(&create->list);
spin_unlock(&__kthread_create_lock); spin_unlock(&__kthread_create_lock);

View File

@ -34,6 +34,8 @@
#define CLONE_SIGNAL (1UL << 1) #define CLONE_SIGNAL (1UL << 1)
#define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间 #define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
#define PCB_NAME_LEN 16
struct thread_struct struct thread_struct
{ {
// 内核层栈基指针 // 内核层栈基指针
@ -57,8 +59,8 @@ struct thread_struct
#define PF_KTHREAD (1UL << 0) // 内核线程 #define PF_KTHREAD (1UL << 0) // 内核线程
#define PF_NEED_SCHED (1UL << 1) // 进程需要被调度 #define PF_NEED_SCHED (1UL << 1) // 进程需要被调度
#define PF_VFORK (1UL << 2) // 标志进程是否由于vfork而存在资源共享 #define PF_VFORK (1UL << 2) // 标志进程是否由于vfork而存在资源共享
#define PF_KFORK (1UL << 3) // 标志在内核态下调用fork临时标记do_fork()结束后会将其复位) #define PF_KFORK (1UL << 3) // 标志在内核态下调用fork临时标记do_fork()结束后会将其复位)
#define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结 #define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结
/** /**
* @brief * @brief
@ -73,6 +75,8 @@ struct process_control_block
int64_t preempt_count; // 持有的自旋锁的数量 int64_t preempt_count; // 持有的自旋锁的数量
long signal; long signal;
long cpu_id; // 当前进程在哪个CPU核心上运行 long cpu_id; // 当前进程在哪个CPU核心上运行
char name[PCB_NAME_LEN];
// 内存空间分布结构体, 记录内存页表和程序段信息 // 内存空间分布结构体, 记录内存页表和程序段信息
struct mm_struct *mm; struct mm_struct *mm;
@ -82,6 +86,10 @@ struct process_control_block
// 连接各个pcb的双向链表 // 连接各个pcb的双向链表
struct List list; struct List list;
//todo:给pcb中加一个spinlock_t成员
//进程自旋锁
// spinlock_t alloc_lock;
// 地址空间范围 // 地址空间范围
// 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff // 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff
// 内核空间: 0xffff 8000 0000 0000 ~ 0xffff ffff ffff ffff // 内核空间: 0xffff 8000 0000 0000 ~ 0xffff ffff ffff ffff
@ -109,7 +117,8 @@ struct process_control_block
}; };
// 将进程的pcb和内核栈融合到一起,8字节对齐 // 将进程的pcb和内核栈融合到一起,8字节对齐
union proc_union { union proc_union
{
struct process_control_block pcb; struct process_control_block pcb;
ul stack[STACK_SIZE / sizeof(ul)]; ul stack[STACK_SIZE / sizeof(ul)];
} __attribute__((aligned(8))); } __attribute__((aligned(8)));

View File

@ -135,8 +135,10 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
// initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, // initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5,
// initial_tss[0].ist6, initial_tss[0].ist7); // initial_tss[0].ist6, initial_tss[0].ist7);
__asm__ __volatile__("movq %%fs, %0 \n\t" : "=a"(prev->thread->fs)); __asm__ __volatile__("movq %%fs, %0 \n\t"
__asm__ __volatile__("movq %%gs, %0 \n\t" : "=a"(prev->thread->gs)); : "=a"(prev->thread->fs));
__asm__ __volatile__("movq %%gs, %0 \n\t"
: "=a"(prev->thread->gs));
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)); __asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs));
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)); __asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
@ -1194,4 +1196,29 @@ int process_fd_alloc(struct vfs_file_t *file)
} }
} }
return fd_num; return fd_num;
} }
/**
* @brief pcb设置名字
*
* @param pcb pcb
* @param pcb_name char数组
*/
static void __set_pcb_name(struct process_control_block *pcb, const char *pcb_name)
{
//todo:给pcb加锁
// spin_lock(&pcb->alloc_lock);
strncpy(pcb->name,pcb_name,PCB_NAME_LEN);
// spin_unlock(&pcb->alloc_lock);
}
/**
* @brief pcb设置名字
*
* @param pcb pcb
* @param pcb_name char数组
*/
void process_set_pcb_name(struct process_control_block *pcb, const char *pcb_name)
{
__set_pcb_name(pcb, pcb_name);
}

View File

@ -222,3 +222,11 @@ extern struct mm_struct initial_mm;
extern struct thread_struct initial_thread; extern struct thread_struct initial_thread;
extern union proc_union initial_proc_union; extern union proc_union initial_proc_union;
extern struct process_control_block *initial_proc[MAX_CPU_NUM]; extern struct process_control_block *initial_proc[MAX_CPU_NUM];
/**
* @brief pcb设置名字
*
* @param pcb pcb
* @param pcb_name char数组
*/
void process_set_pcb_name(struct process_control_block *pcb, const char *pcb_name);

View File

@ -3,15 +3,15 @@
#include <common/spinlock.h> #include <common/spinlock.h>
#include <driver/video/video.h> #include <driver/video/video.h>
#include <sched/cfs.h> #include <sched/cfs.h>
#include <common/string.h>
/** /**
* @brief * @brief
* *
* @param p pcb * @param p pcb
* @param attr * @param attr
* @param user * @param user
* @param pi * @param pi
* @return int * @return int
*/ */
static int __sched_setscheduler(struct process_control_block *p, const struct sched_attr *attr, bool user, bool pi) static int __sched_setscheduler(struct process_control_block *p, const struct sched_attr *attr, bool user, bool pi)
{ {
@ -70,4 +70,7 @@ void sched()
void sched_init() void sched_init()
{ {
sched_cfs_init(); sched_cfs_init();
} }

View File

@ -75,4 +75,5 @@ void sched_init();
* @brief * @brief
* *
*/ */
void sched_update_jiffies(); void sched_update_jiffies();