Support blocking server.

This commit is contained in:
TXuian
2024-04-30 18:17:31 +08:00
parent 9f9e25a98e
commit 3a985252d9
13 changed files with 174 additions and 59 deletions

View File

@@ -41,7 +41,7 @@ typedef struct {
uint64_t valid : 1; // for server to peek new msg
uint64_t done : 1; // for client to check request done
uint64_t init : 1; // for client to check request done
uint64_t reserved : 1;
uint64_t delayed : 1;
uint64_t nr_args : 4;
uint64_t opcode : 8;
uint64_t len : 16;

View File

@@ -28,11 +28,20 @@ Modification:
1. first version
*************************************************/
#include "assert.h"
#include "ipc.h"
#include "multicores.h"
#include "share_page.h"
#include "syscall.h"
#include "task.h"
#define IPCSESSION_MSG(session) ((struct IpcMsg*)((char*)((session)->buf) + (session)->head))
static inline bool is_msg_needed(struct IpcMsg* msg)
{
assert(msg != NULL);
return msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1 && msg->header.done == 0 && msg->header.delayed == 0;
}
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
{
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
@@ -71,10 +80,11 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
}
/* poll with new sessions */
int i = 0;
int nr_sessions_need_to_handle = 0;
int session_idx = 0;
DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node)
{
if (i >= arr_capacity) {
if (session_idx >= arr_capacity) {
break;
}
@@ -90,16 +100,24 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
break;
}
userland_session_arr[i++] = (struct Session) {
userland_session_arr[session_idx] = (struct Session) {
.buf = (void*)server_session->buf_addr,
.capacity = server_session->capacity,
.head = server_session->head,
.tail = server_session->tail,
.id = SERVER_SESSION_BACKEND(server_session)->session_id,
};
struct IpcMsg* msg = IPCSESSION_MSG(&userland_session_arr[session_idx]);
if (is_msg_needed(msg)) {
nr_sessions_need_to_handle++;
}
session_idx++;
}
if (LIKELY(i < arr_capacity)) {
userland_session_arr[i].buf = 0;
if (session_idx < arr_capacity && nr_sessions_need_to_handle == 0) {
userland_session_arr[session_idx].buf = 0;
sys_yield(SYS_TASK_YIELD_BLOCK_IPC);
}
return 0;

View File

@@ -76,6 +76,10 @@ static void send_irq_to_user(int irq_num)
buf->header.magic = IPC_MSG_MAGIC;
buf->header.valid = 1;
if (irq_forward_table[irq_num].handle_task->state == BLOCKED) {
xizi_task_manager.task_unblock(irq_forward_table[irq_num].handle_task);
}
/* add session head */
session->head = (session->head + len) % session->capacity;
}

View File

@@ -31,7 +31,7 @@ Modification:
#include "syscall.h"
#include "task.h"
#include "log.h"
#include "assert.h"
int sys_yield(task_yield_reason reason)
{
@@ -46,5 +46,17 @@ int sys_yield(task_yield_reason reason)
xizi_task_manager.task_block(cur_task);
}
}
// wake up all possible server
struct client_session* client_session = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node)
{
assert(client_session != NULL);
struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session);
if (session_backend->server->state == BLOCKED) {
xizi_task_manager.task_unblock(session_backend->server);
}
}
return 0;
}

View File

@@ -291,6 +291,7 @@ static void _task_yield_noschedule(struct TaskMicroDescriptor* task, bool blocki
task->state = READY;
}
task->remain_tick = TASK_CLOCK_TICK;
cur_cpu()->task = NULL;
task_node_add_to_ready_list_back(task);
}