实现设置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
10 changed files with 174 additions and 47 deletions

View File

@ -1,8 +1,8 @@
#include <common/kthread.h>
#include <common/glib.h>
#include <common/kthread.h>
#include <common/spinlock.h>
#include <sched/sched.h>
#include <debug/bug.h>
#include <sched/sched.h>
#include <time/sleep.h>
static spinlock_t __kthread_create_lock; // kthread创建过程的锁
@ -28,28 +28,13 @@ struct kthread_create_info_t
void *data;
int node;
// kthreadd守护进程传递给kthread_create的结果, 成功则返回PCB不成功则该值为负数错误码。若该值为NULL意味着创建过程尚未完成
// kthreadd守护进程传递给kthread_create的结果,
// 成功则返回PCB不成功则该值为负数错误码。若该值为NULL意味着创建过程尚未完成
struct process_control_block *result;
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结构体
*
@ -62,8 +47,7 @@ static inline struct kthread_info_t *to_kthread(struct process_control_block *pc
return pcb->worker_private;
}
static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(void *data), void *data,
int node,
static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(void *data), void *data, int node,
const char name_fmt[], va_list args)
{
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))
{
// 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);
@ -131,8 +131,7 @@ void kthread_exit(long result)
* 当内核线程被唤醒时会运行thread_fn函数并将data作为参数传入。
* 内核线程可以直接返回也可以在kthread_should_stop为真时返回。
*/
struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data), void *data,
int node,
struct process_control_block *kthread_create_on_node(int (*thread_fn)(void *data), void *data, int node,
const char name_fmt[], ...)
{
struct process_control_block *pcb;
@ -171,7 +170,7 @@ static int kthread(void *_create)
// 将当前pcb返回给创建者
create->result = current_pcb;
current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态
current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态
// 发起调度使得当前内核线程休眠。直到创建者通过process_wakeup将当前内核线程唤醒
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);
spin_unlock(&__kthread_create_lock);

View File

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