2023-09-15 00:07:58 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @file thread.h
|
2023-12-02 10:16:14 +08:00
|
|
|
|
* @author ATShining (1358745329@qq.com)
|
2023-09-18 22:13:52 +08:00
|
|
|
|
* @brief
|
2023-09-15 00:07:58 +08:00
|
|
|
|
* @version 0.1
|
|
|
|
|
|
* @date 2023-09-14
|
2023-09-18 22:13:52 +08:00
|
|
|
|
*
|
2023-09-15 00:07:58 +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-03-31 16:06:11 +00:00
|
|
|
|
#include <thread_arch.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
|
|
|
|
|
2024-04-06 16:08:27 +00:00
|
|
|
|
#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
|
2023-11-26 00:15:32 +08:00
|
|
|
|
|
|
|
|
|
|
#define IPC_MSG_SIZE 96
|
|
|
|
|
|
#define MAP_BUF_SIZE 16
|
|
|
|
|
|
#define IPC_USER_SIZE 12
|
|
|
|
|
|
|
|
|
|
|
|
#if (IPC_MSG_SIZE + MAP_BUF_SIZE + IPC_USER_SIZE) > THREAD_MSG_BUG_LEN
|
|
|
|
|
|
#error "IPC MSG len error."
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct ipc_msg
|
|
|
|
|
|
{
|
|
|
|
|
|
union
|
|
|
|
|
|
{
|
|
|
|
|
|
struct
|
|
|
|
|
|
{
|
|
|
|
|
|
umword_t msg_buf[IPC_MSG_SIZE / WORD_BYTES];
|
|
|
|
|
|
umword_t map_buf[MAP_BUF_SIZE / WORD_BYTES];
|
|
|
|
|
|
umword_t user[IPC_USER_SIZE / WORD_BYTES];
|
|
|
|
|
|
};
|
|
|
|
|
|
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
|
|
|
|
|
|
{
|
2023-11-26 00:15:32 +08:00
|
|
|
|
THREAD_IDLE = 0, //!< 空闲状态
|
|
|
|
|
|
THREAD_DEAD = 1, //!< 死亡状态
|
|
|
|
|
|
THREAD_SUSPEND = 2, //!< 只有接收和发送ipc消息时才能挂起
|
|
|
|
|
|
THREAD_READY = 3, //!< 在就绪队列中
|
|
|
|
|
|
THREAD_TODEAD = 4, //!< 该标志标志线程马上要死亡了,执行完必要操作后,进入THREAD_DEAD状态
|
|
|
|
|
|
};
|
|
|
|
|
|
enum thread_ipc_state
|
|
|
|
|
|
{
|
|
|
|
|
|
THREAD_NONE,
|
|
|
|
|
|
THREAD_SEND,
|
|
|
|
|
|
THREAD_RECV,
|
|
|
|
|
|
THREAD_WAIT,
|
|
|
|
|
|
THREAD_TIMEOUT,
|
|
|
|
|
|
THREAD_IPC_ABORT,
|
2023-08-20 20:52:23 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-08-29 16:16:25 +08:00
|
|
|
|
typedef struct msg_buf
|
|
|
|
|
|
{
|
2024-04-06 16:08:27 +00:00
|
|
|
|
void *msg; //!< buf,长度是固定的 @see THREAD_MSG_BUG_LEN
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_MMU)
|
|
|
|
|
|
void *umsg; //!< 消息对应的内核的地址
|
|
|
|
|
|
#endif
|
2023-09-30 14:58:34 +08:00
|
|
|
|
msg_tag_t tag; //!< 存放发送的临时标识
|
2023-08-29 16:16:25 +08:00
|
|
|
|
} msg_buf_t;
|
|
|
|
|
|
|
2023-11-27 21:47:05 +08:00
|
|
|
|
#define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测
|
2023-08-20 20:52:23 +08:00
|
|
|
|
typedef struct thread
|
|
|
|
|
|
{
|
2023-11-26 00:15:32 +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使用
|
|
|
|
|
|
|
2023-11-28 13:46:37 +08:00
|
|
|
|
msg_buf_t msg; //!< 每个线程独有的消息缓存区
|
|
|
|
|
|
slist_head_t wait_send_head; //!< 等待头,那些节点等待给当前线程发送数据
|
|
|
|
|
|
thread_t *last_send_th; //!< 当前线程上次接收到谁的数据
|
2024-01-01 22:57:49 +08:00
|
|
|
|
kobject_t *ipc_kobj; //!< 发送者放到一个ipc对象中
|
2023-11-28 13:46:37 +08:00
|
|
|
|
umword_t user_id; //!< 接收到的user_id
|
2023-11-26 00:15:32 +08:00
|
|
|
|
|
|
|
|
|
|
enum thread_state status; //!< 线程状态
|
|
|
|
|
|
enum thread_ipc_state ipc_status; //!< ipc状态
|
|
|
|
|
|
|
|
|
|
|
|
umword_t magic; //!< maigc
|
2023-08-20 20:52:23 +08:00
|
|
|
|
} thread_t;
|
|
|
|
|
|
|
2024-04-09 19:28:50 +08:00
|
|
|
|
static inline void thread_set_msg_bug(thread_t *th, void *msg, void *umsg)
|
2023-08-29 18:36:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
th->msg.msg = msg;
|
2024-04-06 16:08:27 +00:00
|
|
|
|
th->msg.umsg = umsg;
|
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-06 16:08:27 +00:00
|
|
|
|
{
|
|
|
|
|
|
return th->msg.umsg;
|
|
|
|
|
|
}
|
|
|
|
|
|
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 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);
|
2023-09-11 00:49:51 +08:00
|
|
|
|
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);
|
2023-09-29 12:42:07 +08:00
|
|
|
|
void thread_dead(thread_t *th);
|
|
|
|
|
|
void thread_todead(thread_t *th, bool_t is_sche);
|
2023-11-26 00:15:32 +08:00
|
|
|
|
void thread_ready(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);
|
2024-01-01 22:57:49 +08:00
|
|
|
|
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);
|