Files
mkrtos-real/mkrtos_knl/inc/knl/thread.h

121 lines
3.3 KiB
C
Raw Normal View History

/**
* @file thread.h
* @author zhangzheng (1358745329@qq.com)
2023-09-18 22:13:52 +08:00
* @brief
* @version 0.1
* @date 2023-09-14
2023-09-18 22:13:52 +08:00
*
* @copyright Copyright (c) 2023
2023-09-18 22:13:52 +08:00
*
2023-08-20 20:52:23 +08:00
*/
#pragma once
#include "kobject.h"
#include "scheduler.h"
#include "util.h"
#include "arch.h"
2023-08-28 22:11:49 +08:00
#include "ref.h"
2023-08-27 21:25:09 +08:00
#define THREAD_BLOCK_SIZE 0x400 //!< 线程块大小,栈在块的顶部
2023-09-03 15:55:06 +08:00
struct task;
typedef struct task task_t;
2023-08-30 00:36:52 +08:00
struct thread;
typedef struct thread thread_t;
2023-09-03 15:55:06 +08:00
2023-08-20 20:52:23 +08:00
enum thread_state
{
THREAD_IDLE, //!< 空闲状态
THREAD_DEAD, //!< 死亡状态
2023-08-29 16:16:25 +08:00
THREAD_SUSPEND, //!< 只有接收和发送ipc消息时才能挂起
THREAD_READY, //!< 正常工作状态
THREAD_TODEAD, //!< 该标志标志线程马上要死亡了执行完必要操作后进入THREAD_DEAD状态
2023-08-20 20:52:23 +08:00
};
2023-08-27 16:52:53 +08:00
typedef struct
2023-08-20 20:52:23 +08:00
{
umword_t rg0[4]; //!< r0-r3
umword_t r12;
umword_t lr;
umword_t pc;
umword_t xpsr;
2023-08-27 16:52:53 +08:00
} pf_s_t;
typedef struct pf
{
umword_t rg1[8]; //!< r4-r11
pf_s_t pf_s;
2023-08-20 20:52:23 +08:00
} pf_t;
typedef struct sp_info
{
void *user_sp; //!< 用户态的sp
void *knl_sp; //!< 内核sp
mword_t sp_type; //!< 使用的栈类型
} sp_info_t;
2023-08-29 16:16:25 +08:00
2023-09-03 15:55:06 +08:00
#define THREAD_MSG_BUG_LEN 128UL //!< 默认的消息寄存器大小
2023-08-29 16:16:25 +08:00
#define MSG_BUF_HAS_DATA_FLAGS 0x01U //!< 已经有数据了
2023-09-03 15:55:06 +08:00
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收来自recv_th的消息
#define MSG_BUF_REPLY_FLAGS 0x04U //!< 回复消息给send_th
2023-08-29 16:16:25 +08:00
typedef struct msg_buf
{
2023-09-18 22:13:52 +08:00
void *msg; //!< buf长度是固定的 @see THREAD_MSG_BUG_LEN
// uint8_t len; //!< 这里不是buf的大小而是存储接收或者发送的长度
msg_tag_t tag;
2023-08-29 16:16:25 +08:00
} msg_buf_t;
2023-09-03 15:55:06 +08:00
#define THREAD_MAIGC 0xdeadead //!< 用于栈溢出检测
2023-08-20 20:52:23 +08:00
typedef struct thread
{
kobject_t kobj; //!< 内核对象节点
2023-09-09 12:58:57 +08:00
// slist_head_t wait; //!< 用于等待队列
2023-08-20 20:52:23 +08:00
sched_t sche; //!< 调度节点
kobject_t *task; //!< 绑定的task
sp_info_t sp; //!< sp信息
2023-08-28 22:11:49 +08:00
ram_limit_t *lim; //!< 内存限制
ref_counter_t ref; //!< 引用计数
2023-08-29 16:16:25 +08:00
msg_buf_t msg; //!< 每个线程独有的消息缓存区
2023-08-28 22:11:49 +08:00
enum thread_state status; //!< 线程状态
2023-08-29 18:36:32 +08:00
umword_t magic; //!< maigc
2023-08-20 20:52:23 +08:00
} thread_t;
2023-09-18 22:13:52 +08:00
static inline void thread_set_msg_bug(thread_t *th, void *msg)
2023-08-29 18:36:32 +08:00
{
th->msg.msg = msg;
}
2023-08-20 20:52:23 +08:00
static inline enum thread_state thread_get_status(thread_t *th)
{
return th->status;
}
static inline pf_t *thread_get_pf(thread_t *th)
{
uint8_t *bottom = (uint8_t *)th;
return ((pf_t *)(bottom + THREAD_BLOCK_SIZE)) - 1;
}
static inline thread_t *thread_get_current(void)
{
umword_t sp = arch_get_sp();
2023-08-28 22:11:49 +08:00
thread_t *th = (thread_t *)(ALIGN_DOWN(sp, THREAD_BLOCK_SIZE));
2023-08-20 20:52:23 +08:00
2023-08-28 22:11:49 +08:00
return th;
2023-08-20 20:52:23 +08:00
}
2023-09-03 15:55:06 +08:00
task_t *thread_get_current_task(void);
task_t *thread_get_bind_task(thread_t *th);
2023-08-20 20:52:23 +08:00
static inline pf_t *thread_get_current_pf(void)
{
return thread_get_pf(thread_get_current());
}
2023-08-28 22:11:49 +08:00
void thread_init(thread_t *th, ram_limit_t *lim);
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram, umword_t stack);
2023-08-20 20:52:23 +08:00
thread_t *thread_create(ram_limit_t *ram);
void thread_bind(thread_t *th, kobject_t *tk);
2023-08-28 22:11:49 +08:00
void thread_unbind(thread_t *th);
2023-08-20 20:52:23 +08:00
2023-09-07 23:47:34 +08:00
void thread_send_wait(thread_t *th);
2023-08-20 20:52:23 +08:00
void thread_sched(void);
void thread_suspend(thread_t *th);
void thread_dead(thread_t *th);
void thread_todead(thread_t *th, bool_t is_sche);
2023-08-20 20:52:23 +08:00
void thread_ready(thread_t *th, bool_t is_sche);