Support blocking server.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user