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

295 lines
8.0 KiB
C
Raw Normal View History

/**
* @file thread.h
* @author ATShining (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"
2024-04-27 03:47:45 +00:00
#include <atomics.h>
#include "task.h"
2024-12-27 08:23:26 +08:00
#include "stack.h"
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
#define THREAD_IS_DEBUG 0 //!< 是否开启调试
#define THREAD_CREATE_VM 0x1
#define THREAD_MSG_BUG_LEN CONFIG_THREAD_MSG_BUG_LEN //!< 最小的消息寄存器大小
#define MSG_BUF_HAS_DATA_FLAGS 0x01U //!< 已经有数据了
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收来自recv_th的消息
#define MSG_BUF_REPLY_FLAGS 0x04U //!< 回复消息给send_th
#define IPC_MSG_SIZE (CONFIG_THREAD_IPC_MSG_LEN * sizeof(void *))
#define MAP_BUF_SIZE (CONFIG_THREAD_MAP_BUF_LEN * sizeof(void *))
#define IPC_USER_SIZE (CONFIG_THREAD_USER_BUF_LEN * sizeof(void *))
#if IS_ENABLED(CONFIG_VCPU)
#define IPC_VPUC_MSG_OFFSET (3 * 1024) //!< vcpu 传递消息的偏移量
#endif
// #if ((IPC_MSG_SIZE * WORD_BYTES) + (MAP_BUF_SIZE * WORD_BYTES) + (IPC_USER_SIZE * WORD_BYTES)) > THREAD_MSG_BUG_LEN
// #error "IPC MSG len error."
// #endif
typedef struct ipc_msg
{
union
{
struct
{
umword_t msg_buf[CONFIG_THREAD_IPC_MSG_LEN];
umword_t map_buf[CONFIG_THREAD_MAP_BUF_LEN];
umword_t user[CONFIG_THREAD_USER_BUF_LEN]; //!< 0:pthread使用 1:存放私有信息 2:源端的PID号 3:存放私有信息
};
uint8_t data[THREAD_MSG_BUG_LEN];
};
} ipc_msg_t;
typedef union ipc_timeout
{
umword_t raw;
struct
{
uhmword_t send_timeout;
uhmword_t recv_timeout;
};
} ipc_timeout_t;
static inline ipc_timeout_t ipc_timeout_create2(uhmword_t send_timeout, uhmword_t recv_timeout)
{
return (ipc_timeout_t){
.send_timeout = send_timeout,
.recv_timeout = recv_timeout,
};
}
static inline ipc_timeout_t ipc_timeout_create(umword_t raw)
{
return (ipc_timeout_t){
.raw = raw,
};
}
2023-08-20 20:52:23 +08:00
enum thread_state
{
THREAD_IDLE = 0, //!< 空闲状态
THREAD_SUSPEND = 1, //!< 只有接收和发送ipc消息时才能挂起
THREAD_READY = 2, //!< 在就绪队列中
};
enum thread_ipc_state
{
THREAD_NONE = 0,
THREAD_IPC_ABORT = 1,
2023-08-20 20:52:23 +08:00
};
2023-08-29 16:16:25 +08:00
typedef struct msg_buf
{
void *msg; //!< buf长度是固定的 @see THREAD_MSG_BUG_LEN
#if IS_ENABLED(CONFIG_MMU)
void *umsg; //!< 消息对应的内核的地址
#endif
msg_tag_t tag; //!< 存放发送的临时标识
2023-08-29 16:16:25 +08:00
} msg_buf_t;
2024-12-27 08:23:26 +08:00
typedef struct thread_fast_ipc_item
{
kobject_t *task_bk; //!< 备份task用于快速通信
void *usp_backup; //!< 备份用户栈,用于快速通信
void *msg_buf;
} thread_fast_ipc_item_t;
2025-02-12 17:29:30 +08:00
#define THREAD_FAST_IPC_ITEM_NUM 8
typedef struct thread_fast_ipc_com
{
thread_fast_ipc_item_t fast_ipc_stack_data[THREAD_FAST_IPC_ITEM_NUM]; //!< 栈数据,用于通信栈备份
stack_t fast_ipc_stack; //!< fast ipc stack
slist_head_t fast_ipc_node; //!< 用于加入到task中去。
thread_t *th; //!< 存储当前ipc_com属于那个线程
2025-02-12 17:29:30 +08:00
} thread_fast_ipc_com_t;
2024-12-27 08:23:26 +08:00
2023-11-27 21:47:05 +08:00
#define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测
2023-08-20 20:52:23 +08:00
typedef struct thread
{
2024-12-27 08:23:26 +08:00
kobject_t kobj; //!< 内核对象节点
sched_t sche; //!< 调度节点
kobject_t *task; //!< 绑定的task
sp_info_t sp; //!< sp信息
ram_limit_t *lim; //!< 内存限制
ref_counter_t ref; //!< 引用计数
2023-11-27 21:47:05 +08:00
slist_head_t futex_node; //!< futex使用
2024-04-27 03:47:45 +00:00
#if IS_ENABLED(CONFIG_SMP)
ipi_msg_t ipi_msg_node;
#endif
int cpu;
atomic_t time_count; //!< 运行的时间
bool_t is_vcpu; //!< 是否是vcpu
2024-04-27 03:47:45 +00:00
msg_buf_t msg; //!< 每个线程独有的消息缓存区
umword_t user_id; //!< 接收到的user_id
umword_t knl_bakup_sp; //!< 内核线程备份的sp
enum thread_state status; //!< 线程状态
enum thread_ipc_state ipc_status; //!< ipc状态
slist_head_t release_node;
2025-02-12 17:29:30 +08:00
thread_fast_ipc_com_t *com; //!< fast ipc通信这里用指针是为了减少thread block大小
umword_t magic; //!< maigc
2023-08-20 20:52:23 +08:00
} thread_t;
2025-03-11 17:03:30 +08:00
static inline int thread_get_prio(thread_t *th)
{
return th->sche.prio;
}
static inline int thread_get_cpu(thread_t *th)
{
return th->cpu;
}
static inline void thread_set_cpu(thread_t *th, int cpu)
{
th->cpu = cpu;
_dmb(ish);
}
static inline enum thread_state thread_get_status(thread_t *th)
{
return th->status;
}
static inline void thread_set_state(thread_t *th, enum thread_state status)
{
th->status = status;
_dmb(ish);
}
static inline void thread_set_ipc_state(thread_t *th, enum thread_ipc_state ipc_status)
{
th->ipc_status = ipc_status;
_dmb(ish);
}
static inline enum thread_ipc_state thread_get_ipc_state(thread_t *th)
{
return th->ipc_status;
}
2024-04-09 16:07:36 +00:00
static inline void thread_set_msg_buf(thread_t *th, void *msg, void *umsg)
2023-08-29 18:36:32 +08:00
{
th->msg.msg = msg;
2024-04-10 15:19:02 +00:00
#if IS_ENABLED(CONFIG_MMU)
th->msg.umsg = umsg;
2024-04-10 15:19:02 +00:00
#endif
2023-08-29 18:36:32 +08:00
}
2023-11-19 23:01:35 +08:00
static inline void *thread_get_msg_buf(thread_t *th)
{
2024-04-10 15:19:02 +00:00
#if IS_ENABLED(CONFIG_MMU)
return th->msg.umsg;
2024-04-10 15:19:02 +00:00
#else
return th->msg.msg;
#endif
}
static inline void *thread_get_kmsg_buf(thread_t *th)
2023-11-19 23:01:35 +08:00
{
return th->msg.msg;
}
2023-08-20 20:52:23 +08:00
static inline pf_t *thread_get_pf(thread_t *th)
{
uint8_t *bottom = (uint8_t *)th;
return ((pf_t *)(bottom + CONFIG_THREAD_BLOCK_SIZE)) - 1;
2023-08-20 20:52:23 +08:00
}
static inline thread_t *thread_get_current(void)
{
umword_t sp = arch_get_sp();
2025-02-01 12:26:56 +08:00
thread_t *th = (thread_t *)(ALIGN_DOWN(sp, CONFIG_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
}
2024-12-27 08:23:26 +08:00
static inline int thread_fast_ipc_save(thread_t *th, task_t *tk, void *usp)
{
2024-12-27 08:23:26 +08:00
int ret;
assert(th);
assert(tk);
assert(usp);
thread_fast_ipc_item_t item = {
.task_bk = th->task,
.usp_backup = (void *)arch_get_user_sp(),
.msg_buf = th->msg.msg,
};
2025-02-12 17:29:30 +08:00
ret = stack_push(&th->com->fast_ipc_stack, &item);
2024-12-27 08:23:26 +08:00
if (ret < 0)
{
return ret;
}
th->task = &tk->kobj;
arch_set_user_sp((umword_t)usp); //!< 重新设置
return 0;
}
2024-12-27 08:23:26 +08:00
static inline int thread_fast_ipc_restore(thread_t *th)
{
2024-12-27 08:23:26 +08:00
int ret;
assert(th);
thread_fast_ipc_item_t item;
2025-02-12 17:29:30 +08:00
ret = stack_pop(&th->com->fast_ipc_stack, &item);
2024-12-27 08:23:26 +08:00
if (ret < 0)
{
return ret;
}
th->task = item.task_bk;
th->msg.msg = item.msg_buf;
arch_set_user_sp((umword_t)(item.usp_backup));
return 0;
}
static inline int thread_fast_ipc_pop(thread_t *th, thread_fast_ipc_item_t *item)
{
int ret;
assert(th);
assert(item);
2025-02-12 17:29:30 +08:00
ret = stack_pop(&th->com->fast_ipc_stack, item);
2024-12-27 08:23:26 +08:00
return ret;
}
2023-09-03 15:55:06 +08:00
task_t *thread_get_current_task(void);
2024-04-27 03:47:45 +00:00
task_t *thread_get_task(thread_t *th);
2023-09-03 15:55:06 +08:00
task_t *thread_get_bind_task(thread_t *th);
2025-03-11 17:03:30 +08:00
int thread_set_prio(thread_t *th, int prio);
2023-08-20 20:52:23 +08:00
static inline pf_t *thread_get_current_pf(void)
{
return thread_get_pf(thread_get_current());
}
void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags);
2024-12-27 08:23:26 +08:00
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram);
thread_t *thread_create(ram_limit_t *ram, umword_t flags);
2023-08-20 20:52:23 +08:00
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);
2024-04-09 16:07:36 +00:00
bool_t thread_sched(bool_t is_sche);
2024-08-27 23:02:54 +08:00
int thread_suspend_remote(thread_t *th, bool_t is_sche);
2023-08-20 20:52:23 +08:00
void thread_suspend(thread_t *th);
void thread_ready(thread_t *th, bool_t is_sche);
2024-04-27 03:47:45 +00:00
void thread_ready_remote(thread_t *th, bool_t is_sche);
void thread_suspend_sw(thread_t *th, bool_t is_sche);
2023-11-26 16:09:19 +08:00
void thread_timeout_check(ssize_t tick);
msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id);
int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag,
ipc_timeout_t timout, umword_t *ret_user_id, bool_t is_call);
2025-02-05 14:44:49 +08:00
bool_t thread_is_knl(thread_t *thread);
msg_tag_t thread_fast_ipc_replay(entry_frame_t *f);
msg_tag_t thread_fast_ipc_call(task_t *to_task, entry_frame_t *f, umword_t user_id);