Valid 3 code version
This commit is contained in:
@@ -12,6 +12,7 @@ SRC_FILES := syscall.c \
|
||||
sys_state.c \
|
||||
sys_mmap.c \
|
||||
sys_kill.c \
|
||||
sys_semaphore.c
|
||||
sys_semaphore.c \
|
||||
sys_wait_session.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
@@ -46,35 +46,42 @@ int sys_close_session(struct Thread* cur_task, struct Session* session)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check if session is a client one or a server one */
|
||||
struct session_backend* session_backend = NULL;
|
||||
|
||||
struct client_session* client_session = NULL;
|
||||
DOUBLE_LIST_FOR_EACH_ENTRY(client_session, &cur_task->cli_sess_listhead, node)
|
||||
{
|
||||
if ((uintptr_t)session->buf == client_session->buf_addr) {
|
||||
session_backend = CLIENT_SESSION_BACKEND(client_session);
|
||||
assert(session_backend->client == cur_task);
|
||||
assert(client_session->closed == false);
|
||||
client_session->closed = true;
|
||||
xizi_share_page_manager.delete_share_pages(session_backend);
|
||||
break;
|
||||
/* check if session is a client one or a server one */
|
||||
RbtNode* client_session_node = rbt_search(&cur_task->cli_sess_map, session->id);
|
||||
if (client_session_node != NULL) {
|
||||
struct client_session* client_session = (struct client_session*)client_session_node->data;
|
||||
if (CLIENT_SESSION_BACKEND(client_session)->session_id != session->id || //
|
||||
client_session->buf_addr != (uintptr_t)session->buf) {
|
||||
ERROR("Error closing session from %s: Invalid session\n", cur_task->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* close client session */
|
||||
session_backend = CLIENT_SESSION_BACKEND(client_session);
|
||||
assert(session_backend->client == cur_task);
|
||||
assert(client_session->closed == false);
|
||||
client_session->closed = true;
|
||||
rbt_delete(&cur_task->cli_sess_map, client_session_node->key);
|
||||
xizi_share_page_manager.delete_share_pages(session_backend);
|
||||
}
|
||||
|
||||
if (UNLIKELY(session_backend == NULL)) {
|
||||
struct server_session* server_session = NULL;
|
||||
DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node)
|
||||
{
|
||||
if ((uintptr_t)session->buf == server_session->buf_addr) {
|
||||
session_backend = SERVER_SESSION_BACKEND(server_session);
|
||||
assert(session_backend->server == cur_task);
|
||||
assert(server_session->closed == false);
|
||||
server_session->closed = true;
|
||||
xizi_share_page_manager.delete_share_pages(session_backend);
|
||||
break;
|
||||
}
|
||||
RbtNode* server_session_node = rbt_search(&cur_task->svr_sess_map, session->id);
|
||||
if (server_session_node != NULL) {
|
||||
struct server_session* server_session = (struct server_session*)server_session_node->data;
|
||||
if (SERVER_SESSION_BACKEND(server_session)->session_id != session->id || //
|
||||
server_session->buf_addr != (uintptr_t)session->buf) {
|
||||
ERROR("Error closing session from %s: Invalid session\n", cur_task->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
session_backend = SERVER_SESSION_BACKEND(server_session);
|
||||
assert(session_backend->server == cur_task);
|
||||
assert(server_session->closed == false);
|
||||
server_session->closed = true;
|
||||
rbt_delete(&cur_task->cli_sess_map, server_session_node->key);
|
||||
xizi_share_page_manager.delete_share_pages(session_backend);
|
||||
}
|
||||
|
||||
/* close this session */
|
||||
|
||||
@@ -54,15 +54,15 @@ int sys_mmap(uintptr_t* vaddr, uintptr_t* paddr, int len, int is_dev)
|
||||
}
|
||||
} else {
|
||||
uintptr_t load_vaddr = *vaddr;
|
||||
char* new_paddr = raw_alloc(true_len);
|
||||
char* new_paddr = raw_alloc_by_ownership(cur_task->memspace->userspace_mem_usage.tag, true_len);
|
||||
if (new_paddr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (xizi_share_page_manager.task_map_pages(cur_task, load_vaddr, (uintptr_t)new_paddr, true_len / PAGE_SIZE, false) == (uintptr_t)NULL) {
|
||||
raw_free(new_paddr);
|
||||
raw_free_by_ownership(cur_task->memspace->userspace_mem_usage.tag, new_paddr);
|
||||
return -1;
|
||||
}
|
||||
CreateResourceTag(NULL, &cur_task->memspace->tag, "ANON_MEMORY", TRACER_MEM_FROM_BUDDY_AC_RESOURCE, new_paddr);
|
||||
CreateResourceTag(NULL, &cur_task->memspace->tag, "USER_MEMORY", TRACER_MEM_FROM_BUDDY_AC_RESOURCE, new_paddr);
|
||||
*paddr = (uintptr_t)new_paddr;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,7 @@ Modification:
|
||||
#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.handling == 0;
|
||||
}
|
||||
|
||||
extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
|
||||
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
|
||||
{
|
||||
struct Thread* cur_task = cur_cpu()->task;
|
||||
@@ -50,46 +43,40 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct double_list_node* cur_node = NULL;
|
||||
struct server_session* server_session = NULL;
|
||||
|
||||
/* update old sessions */
|
||||
for (int i = 0; i < arr_capacity; i++) {
|
||||
if (UNLIKELY(userland_session_arr[i].buf == NULL)) {
|
||||
break;
|
||||
}
|
||||
cur_node = cur_task->svr_sess_listhead.next;
|
||||
server_session = CONTAINER_OF(cur_node, struct server_session, node);
|
||||
if (UNLIKELY(server_session->buf_addr != (uintptr_t)userland_session_arr[i].buf)) {
|
||||
ERROR("mismatched old session addr, user buf: %x, server buf: %x\n", userland_session_arr[i].buf, server_session->buf_addr);
|
||||
int cur_userland_idx = 0;
|
||||
while (!queue_is_empty(&cur_task->sessions_in_handle)) {
|
||||
struct server_session* server_session = (struct server_session*)queue_front(&cur_task->sessions_in_handle)->data;
|
||||
|
||||
// wrong session info
|
||||
if (userland_session_arr[cur_userland_idx].id != SERVER_SESSION_BACKEND(server_session)->session_id || //
|
||||
(uintptr_t)userland_session_arr[cur_userland_idx].buf != server_session->buf_addr) {
|
||||
ERROR("mismatched old session from %s, user buf: %x, server buf: %x\n", cur_task->name, userland_session_arr[cur_userland_idx].buf, server_session->buf_addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// update session_backend
|
||||
// if current session is handled
|
||||
if (server_session->head != userland_session_arr[i].head) {
|
||||
struct Thread* client = SERVER_SESSION_BACKEND(server_session)->client;
|
||||
if (client->state == BLOCKED) {
|
||||
xizi_task_manager.task_unblock(client);
|
||||
} else {
|
||||
client->advance_unblock = true;
|
||||
}
|
||||
}
|
||||
server_session->head = userland_session_arr[i].head;
|
||||
server_session->tail = userland_session_arr[i].tail;
|
||||
doubleListDel(cur_node);
|
||||
doubleListAddOnBack(cur_node, &cur_task->svr_sess_listhead);
|
||||
ksemaphore_signal(&xizi_task_manager.semaphore_pool, SERVER_SESSION_BACKEND(server_session)->client_sem_to_wait);
|
||||
|
||||
server_session->head = userland_session_arr[cur_userland_idx].head;
|
||||
server_session->tail = userland_session_arr[cur_userland_idx].tail;
|
||||
userland_session_arr[cur_userland_idx].buf = NULL;
|
||||
userland_session_arr[cur_userland_idx].id = -1;
|
||||
|
||||
dequeue(&cur_task->sessions_in_handle);
|
||||
cur_userland_idx++;
|
||||
}
|
||||
int nr_handled_calls = cur_userland_idx;
|
||||
|
||||
/* poll with new sessions */
|
||||
int nr_sessions_need_to_handle = 0;
|
||||
bool has_middle_delete = false;
|
||||
int session_idx = 0;
|
||||
DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node)
|
||||
{
|
||||
if (session_idx >= arr_capacity) {
|
||||
cur_userland_idx = 0;
|
||||
while (!queue_is_empty(&cur_task->sessions_to_be_handle)) {
|
||||
if (cur_userland_idx == arr_capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct server_session* server_session = (struct server_session*)queue_front(&cur_task->sessions_to_be_handle)->data;
|
||||
|
||||
if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) {
|
||||
// client had closed it, then server will close it too
|
||||
struct session_backend* session_backend = SERVER_SESSION_BACKEND(server_session);
|
||||
@@ -98,12 +85,11 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
|
||||
assert(server_session->closed == false);
|
||||
server_session->closed = true;
|
||||
xizi_share_page_manager.delete_share_pages(session_backend);
|
||||
// signal that there is a middle deletion of session
|
||||
has_middle_delete = true;
|
||||
break;
|
||||
dequeue(&cur_task->sessions_to_be_handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
userland_session_arr[session_idx] = (struct Session) {
|
||||
userland_session_arr[cur_userland_idx++] = (struct Session) {
|
||||
.buf = (void*)server_session->buf_addr,
|
||||
.capacity = server_session->capacity,
|
||||
.head = server_session->head,
|
||||
@@ -111,25 +97,18 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
|
||||
.id = SERVER_SESSION_BACKEND(server_session)->session_id,
|
||||
};
|
||||
|
||||
struct IpcMsg* msg = IPCSESSION_MSG(&userland_session_arr[session_idx]);
|
||||
if (msg != NULL && is_msg_needed(msg)) {
|
||||
nr_sessions_need_to_handle++;
|
||||
}
|
||||
|
||||
session_idx++;
|
||||
enqueue(&cur_task->sessions_in_handle, 0, (void*)server_session);
|
||||
dequeue(&cur_task->sessions_to_be_handle);
|
||||
}
|
||||
|
||||
if (session_idx < arr_capacity) {
|
||||
userland_session_arr[session_idx].buf = NULL;
|
||||
if (!has_middle_delete && nr_sessions_need_to_handle == 0) {
|
||||
if (cur_task->advance_unblock) {
|
||||
cur_task->advance_unblock = false;
|
||||
} else {
|
||||
xizi_task_manager.task_yield_noschedule(cur_task, false);
|
||||
xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task);
|
||||
}
|
||||
}
|
||||
// end of userland copy
|
||||
if (cur_userland_idx < arr_capacity) {
|
||||
userland_session_arr[cur_userland_idx].buf = NULL;
|
||||
}
|
||||
|
||||
if (queue_is_empty(&cur_task->sessions_in_handle) && queue_is_empty(&cur_task->sessions_to_be_handle)) {
|
||||
xizi_task_manager.task_yield_noschedule(cur_task, false);
|
||||
xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -35,8 +35,6 @@ Modification:
|
||||
#include "syscall.h"
|
||||
#include "task.h"
|
||||
|
||||
#define SERVER_DIR_NAME_SIZE 14
|
||||
|
||||
int sys_register_as_server(char* name)
|
||||
{
|
||||
// get server thread
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "syscall.h"
|
||||
#include "task.h"
|
||||
|
||||
extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uint32_t sem_id);
|
||||
extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
|
||||
int sys_semaphore(sys_sem_option op, int param)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file sys_wait_session.c
|
||||
* @brief
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2023.08.25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: sys_poll_session.c
|
||||
Description: server poll its connected sessions
|
||||
Others:
|
||||
History:
|
||||
1. Date: 2023-08-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#include "multicores.h"
|
||||
#include "share_page.h"
|
||||
|
||||
#include "syscall.h"
|
||||
|
||||
extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, sem_id_t sem_id);
|
||||
int sys_wait_session(struct Session* userland_session)
|
||||
{
|
||||
struct Thread* cur_task = cur_cpu()->task;
|
||||
|
||||
RbtNode* client_session_node = rbt_search(&cur_task->cli_sess_map, userland_session->id);
|
||||
if (client_session_node == NULL) {
|
||||
ERROR("Error waiting session from %s: Invalid session %d\n", cur_task->name, userland_session->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct client_session* client_session = (struct client_session*)client_session_node->data;
|
||||
if (CLIENT_SESSION_BACKEND(client_session)->session_id != userland_session->id || //
|
||||
client_session->buf_addr != (uintptr_t)userland_session->buf) {
|
||||
ERROR("Error waiting session from %s: Invalid session %d\n", cur_task->name, userland_session->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* handle calling */
|
||||
struct session_backend* session_backend = CLIENT_SESSION_BACKEND(client_session);
|
||||
struct Thread* server_to_call = session_backend->server;
|
||||
enqueue(&server_to_call->sessions_to_be_handle, 0, (void*)&session_backend->server_side);
|
||||
assert(!queue_is_empty(&server_to_call->sessions_to_be_handle));
|
||||
|
||||
ksemaphore_wait(&xizi_task_manager.semaphore_pool, cur_task, session_backend->client_sem_to_wait);
|
||||
if (server_to_call->state == BLOCKED) {
|
||||
xizi_task_manager.task_unblock(session_backend->server);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -37,27 +37,5 @@ int sys_yield(task_yield_reason reason)
|
||||
{
|
||||
struct Thread* cur_task = cur_cpu()->task;
|
||||
xizi_task_manager.task_yield_noschedule(cur_task, false);
|
||||
|
||||
// handle ipc block
|
||||
if ((reason & SYS_TASK_YIELD_BLOCK_IPC) != 0) {
|
||||
if (cur_task->advance_unblock) {
|
||||
cur_task->advance_unblock = false;
|
||||
return 0;
|
||||
} else {
|
||||
xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, 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;
|
||||
}
|
||||
@@ -83,6 +83,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
|
||||
case SYSCALL_SLEEP:
|
||||
ret = sys_sleep((intptr_t)param1);
|
||||
break;
|
||||
case SYSCALL_WAIT_SESSION:
|
||||
ret = sys_wait_session((struct Session*)param1);
|
||||
break;
|
||||
default:
|
||||
ERROR("Unsurport syscall(%d) right now\n", sys_num);
|
||||
ret = -1;
|
||||
|
||||
Reference in New Issue
Block a user