Support smp. TODO: delete all inner kernel locks.

This commit is contained in:
TXuian 2024-03-15 16:01:30 +08:00
parent 892613a0d5
commit d987bf0357
34 changed files with 531 additions and 150 deletions

View File

@ -74,7 +74,7 @@ Modification:
#include "cortex_a9.h" #include "cortex_a9.h"
#define NR_CPU 1 #define NR_CPU 4
__attribute__((always_inline)) static inline uint32_t user_mode() __attribute__((always_inline)) static inline uint32_t user_mode()
{ {

View File

@ -232,15 +232,15 @@ static struct DCacheDone dcache_done = {
struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag) struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag)
{ {
/* init icache */ /* init icache */
icache_done.enable(); // icache_done.enable();
// icache_done.disable(); icache_done.disable();
return &icache_done; return &icache_done;
} }
struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag) struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag)
{ {
/* init dcache */ /* init dcache */
dcache_done.enable(); // dcache_done.enable();
// dcache_done.disable(); dcache_done.disable();
return &dcache_done; return &dcache_done;
} }

View File

@ -447,11 +447,9 @@ bool tracer_delete_trace(struct TraceTag* target, struct TraceTag* owner)
return true; return true;
} }
static struct spinlock ac_tracer_lock;
void tracer_init(void) void tracer_init(void)
{ {
/* init sys_tracer, the manager */ /* init sys_tracer, the manager */
spinlock_init(&ac_tracer_lock, "tracerlock");
spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap"); spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap");
spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap"); spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap");
memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock)); memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock));

View File

@ -32,31 +32,31 @@ all: init test_fs simple_client simple_server shell fs_server test_priority read
bin: bin:
@mkdir -p bin @mkdir -p bin
shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm
test_priority: test_priority.o libserial.o usyscall.o test_priority: test_priority.o libserial.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm

View File

@ -32,7 +32,7 @@ int main(int argc, char* argv[])
exit(); exit();
} }
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
printf("Syscall Spawn shell failed\n"); printf("Syscall Spawn shell failed\n");
} }

View File

@ -113,10 +113,10 @@ int main(int argc, char** argv)
itoa(id - 1, id_buf, 10); itoa(id - 1, id_buf, 10);
char* shell_task_param[3] = { "/simple_client", id_buf, 0 }; char* shell_task_param[3] = { "/simple_client", id_buf, 0 };
if ((fd = open(&session, shell_task_param[0])) >= 0) { if ((fd = open(&session, shell_task_param[0])) >= 0) {
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
printf("Syscall Spawn simple_client failed\n"); printf("Syscall Spawn simple_client failed\n");
} }
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
printf("Syscall Spawn simple_client failed\n"); printf("Syscall Spawn simple_client failed\n");
} }
close(&session, fd); close(&session, fd);

View File

@ -13,8 +13,8 @@ cflags = -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=so
c_useropts = -O0 c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app

View File

@ -10,6 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
#include "usyscall.h" #include "usyscall.h"
#include "libmem.h"
static int static int
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
return ret; return ret;
} }
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
{ {
struct KernReadTool read_tool = { int file_size = ipc_fsize(session, fd);
.session = session, void* img = malloc(file_size);
.fd = fd, int read_len = 0, cur_read_len = 0;
.ipc_read = ipc_read, while (read_len < file_size) {
}; cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096;
return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0); read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len);
}
int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0);
free(img);
return ret;
} }
int exit() int exit()

View File

@ -51,15 +51,10 @@ typedef union {
} sys_state_info; } sys_state_info;
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
typedef int (*ipc_fsize_fn)(struct Session* session, int fd);
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
struct KernReadTool { int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
struct Session* session;
int fd;
ipc_read_fn ipc_read;
};
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv);
int exit(); int exit();
int yield(); int yield();
int register_server(char* name); int register_server(char* name);

View File

@ -18,6 +18,7 @@ c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/fs/fs_server/include \ -I$(KERNEL_ROOT)/services/fs/fs_server/include \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app

View File

@ -10,6 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
#include "usyscall.h" #include "usyscall.h"
#include "libmem.h"
static int static int
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
return ret; return ret;
} }
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
{ {
struct KernReadTool read_tool = { int file_size = ipc_fsize(session, fd);
.session = session, void* img = malloc(file_size);
.fd = fd, int read_len = 0, cur_read_len = 0;
.ipc_read = ipc_read, while (read_len < file_size) {
}; cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096;
return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0); read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len);
}
int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0);
free(img);
return ret;
} }
int exit() int exit()

View File

@ -51,15 +51,10 @@ typedef union {
} sys_state_info; } sys_state_info;
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
typedef int (*ipc_fsize_fn)(struct Session* session, int fd);
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
struct KernReadTool { int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
struct Session* session;
int fd;
ipc_read_fn ipc_read;
};
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv);
int exit(); int exit();
int yield(); int yield();
int register_server(char* name); int register_server(char* name);

View File

@ -18,6 +18,7 @@ c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/fs/fs_server/include \ -I$(KERNEL_ROOT)/services/fs/fs_server/include \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app

View File

@ -282,7 +282,7 @@ int IPC_DO_SERVE_FUNC(Ipc_read)(int* fd, char* dst, int* offset, int* len)
int cur_read_len = InodeRead(ip, dst, *offset, *len); int cur_read_len = InodeRead(ip, dst, *offset, *len);
return *len; return cur_read_len;
} }
int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len) int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len)
@ -305,18 +305,36 @@ int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len)
return cur_write_len; return cur_write_len;
} }
int IPC_DO_SERVE_FUNC(Ipc_fsize)(int* fd)
{
struct FileDescriptor* fdp = GetFileDescriptor(*fd);
if (!fdp) {
printf("read: fd invalid\n");
return -1;
}
struct Inode* ip = fdp->data;
if (ip->type != FS_FILE) {
printf("read: %s Is not a file\n", fdp->path);
return -1;
}
return ip->size;
}
IPC_SERVER_INTERFACE(Ipc_ls, 1); IPC_SERVER_INTERFACE(Ipc_ls, 1);
IPC_SERVER_INTERFACE(Ipc_cd, 1); IPC_SERVER_INTERFACE(Ipc_cd, 1);
IPC_SERVER_INTERFACE(Ipc_mkdir, 1); IPC_SERVER_INTERFACE(Ipc_mkdir, 1);
IPC_SERVER_INTERFACE(Ipc_delete, 1); IPC_SERVER_INTERFACE(Ipc_delete, 1);
IPC_SERVER_INTERFACE(Ipc_cat, 1); IPC_SERVER_INTERFACE(Ipc_cat, 1);
IPC_SERVER_INTERFACE(Ipc_fsize, 1);
IPC_SERVER_INTERFACE(Ipc_open, 1); IPC_SERVER_INTERFACE(Ipc_open, 1);
IPC_SERVER_INTERFACE(Ipc_close, 1); IPC_SERVER_INTERFACE(Ipc_close, 1);
IPC_SERVER_INTERFACE(Ipc_read, 4); IPC_SERVER_INTERFACE(Ipc_read, 4);
IPC_SERVER_INTERFACE(Ipc_write, 4); IPC_SERVER_INTERFACE(Ipc_write, 4);
IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9, IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 10,
Ipc_ls, Ipc_ls,
Ipc_cd, Ipc_cd,
Ipc_mkdir, Ipc_mkdir,
@ -325,7 +343,8 @@ IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9,
Ipc_open, Ipc_open,
Ipc_close, Ipc_close,
Ipc_read, Ipc_read,
Ipc_write); Ipc_write,
Ipc_fsize);
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {

View File

@ -17,6 +17,7 @@ c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app

View File

@ -63,4 +63,10 @@ IPC_INTERFACE(Ipc_write, 4, fd, src, offset, len, sizeof(int), *(int*)len, sizeo
int write(struct Session* session, int fd, char* src, int offset, int len) int write(struct Session* session, int fd, char* src, int offset, int len)
{ {
return IPC_CALL(Ipc_write)(session, &fd, src, &offset, &len); return IPC_CALL(Ipc_write)(session, &fd, src, &offset, &len);
}
IPC_INTERFACE(Ipc_fsize, 1, fd, sizeof(int));
int fsize(struct Session* session, int fd)
{
return IPC_CALL(Ipc_fsize)(session, &fd);
} }

View File

@ -15,13 +15,14 @@
#include "libipc.h" #include "libipc.h"
IPC_SERVICES(IpcFsServer, Ipc_ls, Ipc_cd, Ipc_mkdir, Ipc_delete, Ipc_cat, IPC_SERVICES(IpcFsServer, Ipc_ls, Ipc_cd, Ipc_mkdir, Ipc_delete, Ipc_cat,
Ipc_open, Ipc_close, Ipc_read, Ipc_write); Ipc_open, Ipc_close, Ipc_read, Ipc_write, Ipc_fsize);
int ls(struct Session* session, char* path); int ls(struct Session* session, char* path);
int cd(struct Session* session, char* path); int cd(struct Session* session, char* path);
int mkdir(struct Session* session, char* path); int mkdir(struct Session* session, char* path);
int rm(struct Session* session, char* path); int rm(struct Session* session, char* path);
int cat(struct Session* session, char* path); int cat(struct Session* session, char* path);
int fsize(struct Session* session, int fd);
int open(struct Session* session, char* path); int open(struct Session* session, char* path);
int close(struct Session* session, int fd); int close(struct Session* session, int fd);

View File

@ -1,4 +1,4 @@
SRC_DIR := ipc SRC_DIR := ipc memory
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

@ -15,8 +15,8 @@ objdump = ${toolchain}objdump
c_useropts = -O0 c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ INC_DIR = -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app

View File

@ -12,11 +12,14 @@ user_ldflags = -N -Ttext 0
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
c_useropts = -O0 c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/app \ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/lib/ipc -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/lib/ipc
all: all: libmem.o
@mv $^ ../../app
%.o: %.c %.o: %.c
@echo "cc $^" @echo "cc $^"

View File

@ -0,0 +1,369 @@
/*
* mm.c - malloc using segregated list
* KAIST
* Tony Kim
*
* In this approach,
* Every block has a header and a footer
* in which header contains reallocation information, size, and allocation info
* and footer contains size and allocation info.
* Free list are tagged to the segregated list.
* Therefore all free block contains pointer to the predecessor and successor.
* The segregated list headers are organized by 2^k size.
*
*/
#include "libmem.h"
#include "usyscall.h"
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~0x7)
// My additional Macros
#define WSIZE 4 // word and header/footer size (bytes)
#define DSIZE 8 // double word size (bytes)
#define INITCHUNKSIZE (1 << 6)
#define CHUNKSIZE (1 << 12) //+(1<<7)
#define LISTLIMIT 20
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
// Pack a size and allocated bit into a word
#define PACK(size, alloc) ((size) | (alloc))
// Read and write a word at address p
#define GET(p) (*(unsigned int*)(p))
#define PUT(p, val) (*(unsigned int*)(p) = (val) | GET_TAG(p))
#define PUT_NOTAG(p, val) (*(unsigned int*)(p) = (val))
// Store predecessor or successor pointer for free blocks
#define SET_PTR(p, ptr) (*(unsigned int*)(p) = (unsigned int)(ptr))
// Read the size and allocation bit from address p
#define GET_SIZE(p) (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)
#define GET_TAG(p) (GET(p) & 0x2)
#define SET_RATAG(p) (GET(p) |= 0x2)
#define REMOVE_RATAG(p) (GET(p) &= ~0x2)
// Address of block's header and footer
#define HDRP(ptr) ((char*)(ptr)-WSIZE)
#define FTRP(ptr) ((char*)(ptr) + GET_SIZE(HDRP(ptr)) - DSIZE)
// Address of (physically) next and previous blocks
#define NEXT_BLKP(ptr) ((char*)(ptr) + GET_SIZE((char*)(ptr)-WSIZE))
#define PREV_BLKP(ptr) ((char*)(ptr)-GET_SIZE((char*)(ptr)-DSIZE))
// Address of free block's predecessor and successor entries
#define PRED_PTR(ptr) ((char*)(ptr))
#define SUCC_PTR(ptr) ((char*)(ptr) + WSIZE)
// Address of free block's predecessor and successor on the segregated list
#define PRED(ptr) (*(char**)(ptr))
#define SUCC(ptr) (*(char**)(SUCC_PTR(ptr)))
// End of my additional macros
// Global var
void* segregated_free_lists[LISTLIMIT];
// Functions
static void* extend_heap(size_t size);
static void* coalesce(void* ptr);
static void* place(void* ptr, size_t asize);
static void insert_node(void* ptr, size_t size);
static void delete_node(void* ptr);
static uintptr_t userland_heap_base;
static uintptr_t userland_heap_top;
static uintptr_t requested_heap_size;
static void* mem_sbrk(size_t size)
{
uintptr_t userland_heap_size = userland_heap_top - userland_heap_base;
if (userland_heap_size - requested_heap_size >= size) {
void* ret_ptr = (void*)(userland_heap_base + requested_heap_size);
requested_heap_size += size;
return ret_ptr;
}
uintptr_t size_needed = size - (userland_heap_size - requested_heap_size);
userland_heap_top = mmap(userland_heap_top, (uintptr_t)NULL, size_needed, false);
return mem_sbrk(size);
}
static void* extend_heap(size_t size)
{
void* ptr;
size_t asize; // Adjusted size
asize = ALIGN(size);
if ((ptr = mem_sbrk(asize)) == (void*)-1)
return NULL;
// Set headers and footer
PUT_NOTAG(HDRP(ptr), PACK(asize, 0));
PUT_NOTAG(FTRP(ptr), PACK(asize, 0));
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(0, 1));
insert_node(ptr, asize);
return coalesce(ptr);
}
static void insert_node(void* ptr, size_t size)
{
int list = 0;
void* search_ptr = ptr;
void* insert_ptr = NULL;
// Select segregated list
while ((list < LISTLIMIT - 1) && (size > 1)) {
size >>= 1;
list++;
}
// Keep size ascending order and search
search_ptr = segregated_free_lists[list];
while ((search_ptr != NULL) && (size > GET_SIZE(HDRP(search_ptr)))) {
insert_ptr = search_ptr;
search_ptr = PRED(search_ptr);
}
// Set predecessor and successor
if (search_ptr != NULL) {
if (insert_ptr != NULL) {
SET_PTR(PRED_PTR(ptr), search_ptr);
SET_PTR(SUCC_PTR(search_ptr), ptr);
SET_PTR(SUCC_PTR(ptr), insert_ptr);
SET_PTR(PRED_PTR(insert_ptr), ptr);
} else {
SET_PTR(PRED_PTR(ptr), search_ptr);
SET_PTR(SUCC_PTR(search_ptr), ptr);
SET_PTR(SUCC_PTR(ptr), NULL);
segregated_free_lists[list] = ptr;
}
} else {
if (insert_ptr != NULL) {
SET_PTR(PRED_PTR(ptr), NULL);
SET_PTR(SUCC_PTR(ptr), insert_ptr);
SET_PTR(PRED_PTR(insert_ptr), ptr);
} else {
SET_PTR(PRED_PTR(ptr), NULL);
SET_PTR(SUCC_PTR(ptr), NULL);
segregated_free_lists[list] = ptr;
}
}
return;
}
static void delete_node(void* ptr)
{
int list = 0;
size_t size = GET_SIZE(HDRP(ptr));
// Select segregated list
while ((list < LISTLIMIT - 1) && (size > 1)) {
size >>= 1;
list++;
}
if (PRED(ptr) != NULL) {
if (SUCC(ptr) != NULL) {
SET_PTR(SUCC_PTR(PRED(ptr)), SUCC(ptr));
SET_PTR(PRED_PTR(SUCC(ptr)), PRED(ptr));
} else {
SET_PTR(SUCC_PTR(PRED(ptr)), NULL);
segregated_free_lists[list] = PRED(ptr);
}
} else {
if (SUCC(ptr) != NULL) {
SET_PTR(PRED_PTR(SUCC(ptr)), NULL);
} else {
segregated_free_lists[list] = NULL;
}
}
return;
}
static void* coalesce(void* ptr)
{
size_t prev_alloc = GET_ALLOC(HDRP(PREV_BLKP(ptr)));
size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(ptr)));
size_t size = GET_SIZE(HDRP(ptr));
// Do not coalesce with previous block if the previous block is tagged with Reallocation tag
if (GET_TAG(HDRP(PREV_BLKP(ptr))))
prev_alloc = 1;
if (prev_alloc && next_alloc) { // Case 1
return ptr;
} else if (prev_alloc && !next_alloc) { // Case 2
delete_node(ptr);
delete_node(NEXT_BLKP(ptr));
size += GET_SIZE(HDRP(NEXT_BLKP(ptr)));
PUT(HDRP(ptr), PACK(size, 0));
PUT(FTRP(ptr), PACK(size, 0));
} else if (!prev_alloc && next_alloc) { // Case 3
delete_node(ptr);
delete_node(PREV_BLKP(ptr));
size += GET_SIZE(HDRP(PREV_BLKP(ptr)));
PUT(FTRP(ptr), PACK(size, 0));
PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0));
ptr = PREV_BLKP(ptr);
} else { // Case 4
delete_node(ptr);
delete_node(PREV_BLKP(ptr));
delete_node(NEXT_BLKP(ptr));
size += GET_SIZE(HDRP(PREV_BLKP(ptr))) + GET_SIZE(HDRP(NEXT_BLKP(ptr)));
PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0));
PUT(FTRP(NEXT_BLKP(ptr)), PACK(size, 0));
ptr = PREV_BLKP(ptr);
}
insert_node(ptr, size);
return ptr;
}
static void* place(void* ptr, size_t asize)
{
size_t ptr_size = GET_SIZE(HDRP(ptr));
size_t remainder = ptr_size - asize;
delete_node(ptr);
if (remainder <= DSIZE * 2) {
// Do not split block
PUT(HDRP(ptr), PACK(ptr_size, 1));
PUT(FTRP(ptr), PACK(ptr_size, 1));
}
else if (asize >= 100) {
// Split block
PUT(HDRP(ptr), PACK(remainder, 0));
PUT(FTRP(ptr), PACK(remainder, 0));
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(asize, 1));
PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(asize, 1));
insert_node(ptr, remainder);
return NEXT_BLKP(ptr);
}
else {
// Split block
PUT(HDRP(ptr), PACK(asize, 1));
PUT(FTRP(ptr), PACK(asize, 1));
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(remainder, 0));
PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(remainder, 0));
insert_node(NEXT_BLKP(ptr), remainder);
}
return ptr;
}
static bool malloc_inited = false;
int mm_init(void)
{
// init heap
userland_heap_base = task_heap_base();
userland_heap_top = userland_heap_base;
requested_heap_size = 0;
int list;
char* heap_start; // Pointer to beginning of heap
// Initialize segregated free lists
for (list = 0; list < LISTLIMIT; list++) {
segregated_free_lists[list] = NULL;
}
// Allocate memory for the initial empty heap
if ((long)(heap_start = mem_sbrk(4 * WSIZE)) == -1)
return -1;
PUT_NOTAG(heap_start, 0); /* Alignment padding */
PUT_NOTAG(heap_start + (1 * WSIZE), PACK(DSIZE, 1)); /* Prologue header */
PUT_NOTAG(heap_start + (2 * WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
PUT_NOTAG(heap_start + (3 * WSIZE), PACK(0, 1)); /* Epilogue header */
if (extend_heap(INITCHUNKSIZE) == NULL)
return -1;
malloc_inited = true;
return 0;
}
void* malloc(size_t size)
{
while (!malloc_inited) {
mm_init();
}
size_t asize; /* Adjusted block size */
size_t extendsize; /* Amount to extend heap if no fit */
void* ptr = NULL; /* Pointer */
// Ignore size 0 cases
if (size == 0)
return NULL;
// Align block size
if (size <= DSIZE) {
asize = 2 * DSIZE;
} else {
asize = ALIGN(size + DSIZE);
}
int list = 0;
size_t searchsize = asize;
// Search for free block in segregated list
while (list < LISTLIMIT) {
if ((list == LISTLIMIT - 1) || ((searchsize <= 1) && (segregated_free_lists[list] != NULL))) {
ptr = segregated_free_lists[list];
// Ignore blocks that are too small or marked with the reallocation bit
while ((ptr != NULL) && ((asize > GET_SIZE(HDRP(ptr))) || (GET_TAG(HDRP(ptr))))) {
ptr = PRED(ptr);
}
if (ptr != NULL)
break;
}
searchsize >>= 1;
list++;
}
// if free block is not found, extend the heap
if (ptr == NULL) {
extendsize = MAX(asize, CHUNKSIZE);
if ((ptr = extend_heap(extendsize)) == NULL)
return NULL;
}
// Place and divide block
ptr = place(ptr, asize);
// Return pointer to newly allocated block
return ptr;
}
void free(void* ptr)
{
size_t size = GET_SIZE(HDRP(ptr));
REMOVE_RATAG(HDRP(NEXT_BLKP(ptr)));
PUT(HDRP(ptr), PACK(size, 0));
PUT(FTRP(ptr), PACK(size, 0));
insert_node(ptr, size);
coalesce(ptr);
return;
}

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
/** /**
* @file libmalloc.h * @file libmem.h
* @brief support malloc and free in userland * @brief support malloc and free in userland
* @version 3.0 * @version 3.0
* @author AIIT XUOS Lab * @author AIIT XUOS Lab
@ -18,7 +18,7 @@
*/ */
/************************************************* /*************************************************
File name: libmalloc.h File name: libmem.h
Description: support malloc and free in userland Description: support malloc and free in userland
Others: Others:
History: History:

View File

@ -16,9 +16,10 @@ objdump = ${toolchain}objdump
c_useropts = -O0 c_useropts = -O0
INC_DIR = -I$(KERNEL_ROOT)/services/app \ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/lib/memory \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD)
-I$(KERNEL_ROOT)/services/fs/libfs
all: shell_cmd_list.o shell_ext.o shell.o all: shell_cmd_list.o shell_ext.o shell.o
@mv $^ ../../app @mv $^ ../../app

View File

@ -1282,7 +1282,7 @@ void shellExec(Shell* shell)
if (fd < 0) { if (fd < 0) {
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
} else { } else {
if (spawn(&session_fs, fd, read, shell->parser.param[0], shell->parser.param) < 0) { if (spawn(&session_fs, fd, read, fsize, shell->parser.param[0], shell->parser.param) < 0) {
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
} }
close(&session_fs, fd); close(&session_fs, fd);

View File

@ -74,15 +74,9 @@ typedef union {
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
struct KernReadTool {
struct Session* session;
int fd;
ipc_read_fn ipc_read;
};
int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv); int sys_spawn(char* img_start, char* name, char** argv);
int sys_exit(); int sys_exit();
int sys_yield(); int sys_yield();
@ -91,7 +85,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session);
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity); int sys_poll_session(struct Session* userland_session_arr, int arr_capacity);
int sys_close_session(struct Session* session); int sys_close_session(struct Session* session);
int sys_exec(struct KernReadTool* read_tool, char* name, char** argv); int sys_exec(char* img_start, char* name, char** argv);
int sys_state(sys_state_option option, sys_state_info* info); int sys_state(sys_state_option option, sys_state_info* info);
int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev); int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev);

View File

@ -35,7 +35,7 @@ user_apps:
.section .rawdata_init .section .rawdata_init
.globl initapp .globl initapp
initapp: initapp:
.incbin "../services/app/bin/shell" .incbin "../services/app/bin/init"
.section .rawdata_memfs .section .rawdata_memfs
.globl memfs .globl memfs

View File

@ -58,17 +58,17 @@ void configure_cpu(uint32_t cpu)
// arm_icache_enable(); // arm_icache_enable();
// arm_icache_invalidate(); // arm_icache_invalidate();
struct TraceTag main_icache_tag, main_dcache_tag; // struct TraceTag main_icache_tag, main_dcache_tag;
AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); // AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource");
AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); // AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource");
struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); // struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag);
struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); // struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag);
// p_dcache_driver->enable(); // // p_dcache_driver->enable();
// p_dcache_driver->invalidateall(); // // p_dcache_driver->invalidateall();
// p_icache_driver->enable(); // // p_icache_driver->enable();
// p_icache_driver->invalidateall(); // // p_icache_driver->invalidateall();
p_dcache_driver->disable(); // p_dcache_driver->disable();
p_icache_driver->disable(); // p_icache_driver->disable();
// Invalidate SCU copy of TAG RAMs // Invalidate SCU copy of TAG RAMs
scu_secure_invalidate(cpu, all_ways); scu_secure_invalidate(cpu, all_ways);
@ -122,15 +122,14 @@ int main(void)
return -1; return -1;
} }
// scu_enable(); scu_enable();
// configure_cpu(cpu_id); configure_cpu(cpu_id);
spinlock_init(&whole_kernel_lock, "wklock"); spinlock_init(&whole_kernel_lock, "wklock");
} else { } else {
configure_cpu(cpu_id);
spinlock_lock(&whole_kernel_lock); spinlock_lock(&whole_kernel_lock);
configure_cpu(cpu_id);
secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag);
DEBUG_PRINTF("CPU %d init done.\n", cur_cpuid());
spinlock_unlock(&whole_kernel_lock); spinlock_unlock(&whole_kernel_lock);
} }
@ -162,7 +161,7 @@ int main(void)
assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource"));
core_init_done |= (1 << cpu_id); core_init_done |= (1 << cpu_id);
DEBUG("core_init_done: %x\n", core_init_done); LOG_PRINTF("CPU %d init done\n", cpu_id);
spinlock_unlock(&whole_kernel_lock); spinlock_unlock(&whole_kernel_lock);
while (core_init_done != (1 << NR_CPU) - 1) while (core_init_done != (1 << NR_CPU) - 1)

View File

@ -66,18 +66,15 @@ Modification:
/// @param path path to elf file /// @param path path to elf file
/// @param argv arguments giving to main /// @param argv arguments giving to main
/// @return /// @return
int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv)
{ {
/* load img to task */
/* 1. load elf header */
struct elfhdr elf; struct elfhdr elf;
memcpy((void*)&elf, img_start, sizeof(elf));
// pgdir for new task
struct TopLevelPageDirectory pgdir; struct TopLevelPageDirectory pgdir;
pgdir.pd_addr = NULL; pgdir.pd_addr = NULL;
if (ipc_read(session, fd, (char*)&elf, 0, sizeof(elf)) < sizeof(elf) || elf.magic != ELF_MAGIC) {
ERROR("invalide elf file.\n");
goto error_exec;
}
// pgdir for new task
if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) { if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) {
ERROR("create new pgdir failed.\n"); ERROR("create new pgdir failed.\n");
goto error_exec; goto error_exec;
@ -88,10 +85,8 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
uintptr_t load_size = 0; uintptr_t load_size = 0;
struct proghdr ph; struct proghdr ph;
for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) { for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) {
if (ipc_read(session, fd, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) { // load proghdr
ERROR("Read elf header failed\n"); memcpy((char*)&ph, img_start + off, sizeof(ph));
goto error_exec;
}
if (ph.type != ELF_PROG_LOAD) if (ph.type != ELF_PROG_LOAD)
continue; continue;
@ -114,10 +109,7 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
panic("copy elf file to unmapped addr"); panic("copy elf file to unmapped addr");
} }
uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE); uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE);
if (read_size != ipc_read(session, fd, P2V(page_paddr), ph.off + addr_offset, read_size)) { memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size);
ERROR("read size error, off: %d, read len: %d\n", ph.off + addr_offset, read_size);
goto error_exec;
}
} }
} }
@ -193,7 +185,7 @@ error_exec:
return -1; return -1;
} }
int sys_exec(struct KernReadTool* read_tool, char* name, char** argv) int sys_exec(char* img_start, char* name, char** argv)
{ {
/// @todo find a source of mmu_driver_tag instead of requiring from root /// @todo find a source of mmu_driver_tag instead of requiring from root
static struct TraceTag mmu_driver_tag; static struct TraceTag mmu_driver_tag;
@ -204,12 +196,8 @@ int sys_exec(struct KernReadTool* read_tool, char* name, char** argv)
} }
struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag); struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag);
struct TaskMicroDescriptor* current_task = cur_cpu()->task; struct TaskMicroDescriptor* current_task = cur_cpu()->task;
struct Session* session = read_tool->session; int ret = task_exec(current_task, img_start, name, argv);
int fd = read_tool->fd;
ipc_read_fn ipc_read = read_tool->ipc_read;
int ret = task_exec(current_task, session, fd, ipc_read, name, argv);
if (ret >= 0) { if (ret >= 0) {
spinlock_init(&current_task->lock, current_task->name); spinlock_init(&current_task->lock, current_task->name);
p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr)); p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr));

View File

@ -33,8 +33,8 @@ Modification:
#include "syscall.h" #include "syscall.h"
#include "task.h" #include "task.h"
extern int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv); extern int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv);
int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv) int sys_spawn(char* img_start, char* name, char** argv)
{ {
// alloc a new pcb // alloc a new pcb
struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb(); struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb();
@ -44,11 +44,7 @@ int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv)
} }
// init trapframe // init trapframe
arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0); arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0);
if (UNLIKELY(task_exec(new_task_cb, img_start, name, argv)) < 0) {
struct Session* session = read_tool->session;
int fd = read_tool->fd;
ipc_read_fn ipc_read = read_tool->ipc_read;
if (UNLIKELY(task_exec(new_task_cb, session, fd, ipc_read, name, argv)) < 0) {
xizi_task_manager.free_pcb(new_task_cb); xizi_task_manager.free_pcb(new_task_cb);
return -1; return -1;
} }

View File

@ -55,8 +55,17 @@ static inline void _padding(char* name)
void show_tasks(void) void show_tasks(void)
{ {
struct TaskMicroDescriptor* task = NULL; struct TaskMicroDescriptor* task = NULL;
DEBUG_PRINTF("******************************************************\n"); LOG_PRINTF("******************************************************\n");
DEBUG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n"); for (int i = 0; i < NR_CPU; i++) {
LOG_PRINTF("CPU %d: ", i);
if (global_cpus[i].task != NULL) {
LOG_PRINTF("%s\n", global_cpus[i].task->name);
} else {
LOG_PRINTF("NULL\n");
}
}
LOG_PRINTF("******************************************************\n");
LOG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n");
for (int i = 0; i < TASK_MAX_PRIORITY; i++) { for (int i = 0; i < TASK_MAX_PRIORITY; i++) {
if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) { if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) {
continue; continue;
@ -64,19 +73,19 @@ void show_tasks(void)
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
{ {
if (task->state == INIT) if (task->state == INIT)
DEBUG_PRINTF(" INIT "); LOG_PRINTF(" INIT ");
else if (task->state == READY) else if (task->state == READY)
DEBUG_PRINTF(" READY "); LOG_PRINTF(" READY ");
else if (task->state == RUNNING) else if (task->state == RUNNING)
DEBUG_PRINTF("RUNNING "); LOG_PRINTF("RUNNING ");
else if (task->state == DEAD) else if (task->state == DEAD)
DEBUG_PRINTF(" DEAD "); LOG_PRINTF(" DEAD ");
_padding(task->name); _padding(task->name);
DEBUG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick); LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick);
} }
} }
DEBUG_PRINTF("******************************************************\n"); LOG_PRINTF("******************************************************\n");
return; return;
} }
@ -85,8 +94,8 @@ extern struct KBuddy kern_virtmem_buddy;
extern uint32_t kernel_data_end[]; extern uint32_t kernel_data_end[];
void show_mem(void) void show_mem(void)
{ {
DEBUG_PRINTF("*********************************************************\n"); LOG_PRINTF("*********************************************************\n");
DEBUG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n"); LOG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n");
uint32_t total = (PHY_MEM_STOP - V2P(kernel_data_end)) >> 10; uint32_t total = (PHY_MEM_STOP - V2P(kernel_data_end)) >> 10;
uint32_t used = 0; uint32_t used = 0;
@ -96,14 +105,14 @@ void show_mem(void)
} }
used = used >> 10; used = used >> 10;
DEBUG_PRINTF(" %d %d %d\n", total, total - used, used); LOG_PRINTF(" %d %d %d\n", total, total - used, used);
DEBUG_PRINTF("*********************************************************\n"); LOG_PRINTF("*********************************************************\n");
return; return;
} }
void show_cpu(void) void show_cpu(void)
{ {
DEBUG_PRINTF("**********************************************************\n"); LOG_PRINTF("**********************************************************\n");
#ifdef ARCH_SMP #ifdef ARCH_SMP
/// @todo support smp /// @todo support smp
KPrintf(" cpu VALUE \n"); KPrintf(" cpu VALUE \n");
@ -116,10 +125,10 @@ void show_cpu(void)
_padding(current_task->name); _padding(current_task->name);
DEBUG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n"); LOG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n");
DEBUG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick); LOG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick);
DEBUG_PRINTF("***********************************************************\n"); LOG_PRINTF("***********************************************************\n");
return; return;
} }

View File

@ -41,7 +41,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = 0; ret = 0;
break; break;
case SYSCALL_SPAWN: case SYSCALL_SPAWN:
ret = sys_spawn((struct KernReadTool*)param1, (char*)param2, (char**)param3); ret = sys_spawn((char*)param1, (char*)param2, (char**)param3);
break; break;
case SYSCALL_EXIT: case SYSCALL_EXIT:
ret = sys_exit(); ret = sys_exit();
@ -62,7 +62,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = sys_close_session((struct Session*)param1); ret = sys_close_session((struct Session*)param1);
break; break;
case SYSCALL_EXEC: case SYSCALL_EXEC:
ret = sys_exec((struct KernReadTool*)param1, (char*)param2, (char**)param3); ret = sys_exec((char*)param1, (char*)param2, (char**)param3);
break; break;
case SYSCALL_SYS_STATE: case SYSCALL_SYS_STATE:
ret = sys_state(param1, (sys_state_info*)param2); ret = sys_state(param1, (sys_state_info*)param2);

View File

@ -181,34 +181,29 @@ static void _scheduler(struct SchedulerRightGroup right_group)
spinlock_lock(&whole_kernel_lock); spinlock_lock(&whole_kernel_lock);
while (1) { while (1) {
spinlock_unlock(&whole_kernel_lock);
spinlock_lock(&xizi_task_manager.lock);
next_task = NULL; next_task = NULL;
/* find next runnable task */ /* find next runnable task */
assert(cur_cpu()->task == NULL); assert(cur_cpu()->task == NULL);
if (next_task_emergency != NULL) { if (next_task_emergency != NULL) {
next_task = next_task_emergency; next_task = next_task_emergency;
spinlock_lock(&next_task->lock);
next_task->state = RUNNING; next_task->state = RUNNING;
spinlock_unlock(&next_task->lock);
next_task_emergency = NULL; next_task_emergency = NULL;
} else { } else {
next_task = xizi_task_manager.next_runnable_task(); next_task = xizi_task_manager.next_runnable_task();
} }
spinlock_unlock(&xizi_task_manager.lock); spinlock_unlock(&whole_kernel_lock);
/* not a runnable task */ /* not a runnable task */
if (UNLIKELY(next_task == NULL)) { if (UNLIKELY(next_task == NULL) || UNLIKELY(next_task->state != RUNNING)) {
spinlock_lock(&whole_kernel_lock);
continue; continue;
} }
/* a runnable task */
spinlock_lock(&whole_kernel_lock); spinlock_lock(&whole_kernel_lock);
assert(next_task->state == RUNNING);
// p_mmu_driver->LoadPgdirCrit((uintptr_t)V2P(next_task->pgdir.pd_addr), &right_group.intr_driver_tag);
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
struct CPU* cpu = cur_cpu(); struct CPU* cpu = cur_cpu();
cpu->task = next_task; cpu->task = next_task;
// DEBUG_PRINTF("CPU %d switch to task %s\n", cur_cpuid(), next_task->name); p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
context_switch(&cpu->scheduler, next_task->main_thread.context); context_switch(&cpu->scheduler, next_task->main_thread.context);
} }
} }

View File

@ -65,7 +65,7 @@ void intr_irq_dispatch(struct trapframe* tf)
if ((int_info = p_intr_driver->hw_before_irq()) == 0) { if ((int_info = p_intr_driver->hw_before_irq()) == 0) {
return; return;
} }
// spinlock_lock(&whole_kernel_lock); spinlock_lock(&whole_kernel_lock);
DSB(); DSB();
// DEBUG("CPU %d in\n", cur_cpuid()); // DEBUG("CPU %d in\n", cur_cpuid());
@ -96,6 +96,6 @@ void intr_irq_dispatch(struct trapframe* tf)
assert(current_task == cur_cpu()->task); assert(current_task == cur_cpu()->task);
// DEBUG("CPU %d out\n", cur_cpuid()); // DEBUG("CPU %d out\n", cur_cpuid());
// spinlock_unlock(&whole_kernel_lock); spinlock_unlock(&whole_kernel_lock);
p_intr_driver->cpu_irq_enable(); p_intr_driver->cpu_irq_enable();
} }

View File

@ -52,7 +52,7 @@ void software_irq_dispatch(struct trapframe* tf)
assert(p_intr_driver != NULL); assert(p_intr_driver != NULL);
p_intr_driver->cpu_irq_disable(); p_intr_driver->cpu_irq_disable();
// spinlock_lock(&whole_kernel_lock); spinlock_lock(&whole_kernel_lock);
DSB(); DSB();
// DEBUG("CPU %d in\n", cur_cpuid()); // DEBUG("CPU %d in\n", cur_cpuid());
// get current task // get current task
@ -78,10 +78,10 @@ void software_irq_dispatch(struct trapframe* tf)
} }
assert(cur_task == cur_cpu()->task); assert(cur_task == cur_cpu()->task);
if (syscall_num == SYSCALL_EXIT) { if (syscall_num == SYSCALL_EXIT) {
ERROR("Exit reaches"); panic("Exit reaches");
} }
// DEBUG("CPU %d out\n", cur_cpuid()); // DEBUG("CPU %d out\n", cur_cpuid());
// spinlock_unlock(&whole_kernel_lock); spinlock_unlock(&whole_kernel_lock);
p_intr_driver->cpu_irq_enable(); p_intr_driver->cpu_irq_enable();
} }