let the child threads get a dream stack too!

This commit is contained in:
flysand7 2023-09-03 20:32:51 +11:00
parent 32f831bda3
commit 9fa3a65736
12 changed files with 127 additions and 81 deletions

View File

@ -43,6 +43,11 @@ _cia_start_thread:
pop rax ; thread_fn
pop rdi ; ctx
call rax
; Make return value the first arg and call exit syscall
mov rdi, rax
mov rax, 60
syscall
; Just to be sure...
hlt
.exit:
ret

4
cia.c
View File

@ -1,6 +1,10 @@
#include <cia/def.h>
// Base includes
#include <cia/def.h>
#include <cia/internal.h>
// Platform-dependent sources
#include _CIA_OS_CONF

23
include/cia/internal.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <cia/def.h>
#include <stdint.h>
struct Cia_CRT_Params typedef Cia_CRT_Params;
struct Cia_CRT_Params {
u64 stack_size;
u64 tls_image_size;
void *tls_image_base;
};
struct Cia_TCB typedef Cia_TCB;
struct Cia_TCB {
u64 thread_id;
u64 parent_id;
u64 pad0[3];
u64 stack_canary;
u64 pad1[2];
};

View File

@ -1,6 +1,8 @@
#pragma once
extern _Thread_local int errno;
// errno-base.h
#define EPERM 1
#define ENOENT 2

View File

@ -55,7 +55,7 @@ struct _RT_Thread {
void *handle;
};
static _RT_Status _rt_thread_current(_RT_Thread *thread);
static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx);
static _RT_Status _rt_thread_create(_RT_Thread *thread, int (*thread_fn)(void *ctx), void *ctx);
static _RT_Status _rt_thread_join(_RT_Thread *thread);
static _RT_Status _rt_thread_detach(_RT_Thread *thread);
static _RT_Status _rt_thread_terminate(_RT_Thread *thread);

View File

@ -15,6 +15,8 @@
#include <tinyrt.h>
#include "../os/linux/tinyrt.c"
#include <cia/internal.h>
#include <cia/mem.h>
#include "../src/cia-mem/util.c"
#include "../src/cia-mem/allocator.c"
@ -23,14 +25,6 @@
#include "stack.c"
struct Thread_Control_Block typedef Thread_Control_Block;
struct Thread_Control_Block {
u64 thread_id;
u64 pad0[4];
u64 stack_canary;
u64 pad1[2];
};
struct Elf_Image typedef Elf_Image;
struct Elf_Image {
Cia_Arena arena;
@ -107,6 +101,7 @@ struct Stage3_Info_Struct {
Elf_Image *ldso;
void *stack_base;
u64 stack_size;
void *tls_image;
u64 tls_size;
};
@ -356,7 +351,7 @@ static void ld_stage3_entry(u64 has_new_stack, void *ctx) {
Stage3_Info_Struct *info = ctx;
_dbg_printf("Stack: %x-%x\n", info->stack_base, (u8 *)info->stack_base+info->stack_size);
// Set up the thread control block
Thread_Control_Block *tcb = cia_ptr_alignf((u8*)info->stack_base + info->tls_size, 1*MB);
Cia_TCB *tcb = cia_ptr_alignf((u8*)info->stack_base + info->tls_size, info->stack_size/2);
tcb->thread_id = 0;
tcb->stack_canary = 0x12345678fedcba98;
// Copy TLS initialization image below TCB
@ -377,6 +372,7 @@ static void ld_stage3_entry(u64 has_new_stack, void *ctx) {
for(int i = 0; i < tls_image_size; ++i) {
tls_image[i] = tls_image_base[i];
}
info->tls_image = tls_image_base;
}
}
// Set up the thread pointer
@ -386,6 +382,10 @@ static void ld_stage3_entry(u64 has_new_stack, void *ctx) {
sys_exit(1);
}
_dbg_printf("Entered loader stage 3. Entering main executable\n");
void (*crt_entry)() = elf_addr(info->app, ((Elf64_Ehdr *)info->app->base)->e_entry);
crt_entry();
Cia_CRT_Params params;
params.stack_size = info->stack_size/2;
params.tls_image_size = info->tls_size;
params.tls_image_base = info->tls_image;
void (*crt_entry)(Cia_CRT_Params *params) = elf_addr(info->app, ((Elf64_Ehdr *)info->app->base)->e_entry);
crt_entry(&params);
}

View File

@ -1,6 +1,10 @@
#pragma once
static u64 cia_stack_size;
static u64 cia_tls_image_size;
static void *cia_tls_image_base;
#include <linux/futex.h>
#include <sys/mman.h>
#include <errno.h>
@ -9,4 +13,5 @@
#include "entry.c"
#include <tinyrt.h>
#include "tinyrt.c"
#include "tinyrt-threads.c"

View File

@ -14,7 +14,10 @@ void __stack_chk_fail(void) {
extern int main(int argc, char **argv, char **envp);
static void _fileapi_init();
void _start() {
void _start(Cia_CRT_Params *params) {
cia_stack_size = params->stack_size;
cia_tls_image_size = params->tls_image_size;
cia_tls_image_base = params->tls_image_base;
// Get the envp
// char **envp = argv + (argc + 1);
// init(argc, argv, envp);

71
os/linux/tinyrt-threads.c Normal file
View File

@ -0,0 +1,71 @@
extern i64 _cia_start_thread(
u64 flags,
void *stack_base,
int *parent_tid,
int *child_tid,
void *tls,
int (*thread_fn)(void *ctx),
void *ctx
);
static _RT_Status _rt_thread_current(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_create(_RT_Thread *thread, int (*thread_fn)(void *ctx), void *ctx) {
// Create the memory for stack
u64 mmap_prot = PROT_READ|PROT_WRITE;
u64 mmap_flags = MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE;
void *stack_base = sys_mmap(0, 2*cia_stack_size, mmap_prot, mmap_flags, -1, 0);
if((i64)stack_base < 0) {
return _RT_ERROR_GENERIC;
}
void *stack = (u8*)stack_base + 2*cia_stack_size;
// Find the TLS base and initialize the tls
Cia_TCB *tcb = (void *)((u64)((u8 *)stack - 1) & ~(cia_stack_size - 1));
tcb->stack_canary = 0x12345678deadbeef;
u8 *tls_base = (u8 *)tcb - cia_tls_image_size;
for(int i = 0; i < cia_tls_image_size; ++i) {
tls_base[i] = ((u8 *)cia_tls_image_base)[i];
}
// Create the new thread
u64 flags = 0;
// flags |= CLONE_CHILD_CLEARTID;
// flags |= CLONE_PARENT_SETTID;
flags |= CLONE_FS;
flags |= CLONE_FILES;
flags |= CLONE_SIGHAND;
flags |= CLONE_THREAD;
flags |= CLONE_VM;
flags |= CLONE_SYSVSEM;
int *child_tid = (int *)&tcb->thread_id;
int *parent_tid = (int *)&tcb->parent_id;
*child_tid = 1;
*parent_tid = 0;
i64 ret = _cia_start_thread(flags, stack, parent_tid, child_tid, 0, thread_fn, ctx);
if(ret < 0) {
return _RT_ERROR_GENERIC;
}
return _RT_STATUS_OK;
}
static _RT_Status _rt_thread_join(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_detach(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_terminate(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_sleep(u64 time) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_get_timer_freq(u64 *freq) {
return _RT_ERROR_NOT_IMPLEMENTED;
}

View File

@ -1,76 +1,10 @@
// See src/tinyrt.h file for the interface this file implements
extern i64 _cia_start_thread(
u64 flags,
void *stack_base,
int *parent_tid,
int *child_tid,
void *tls,
void (*thread_fn)(void *ctx),
void *ctx
);
_Noreturn static void _rt_program_exit(int code) {
sys_exit(code);
}
static _RT_Status _rt_thread_current(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx) {
// Create the memory for stack
u64 mmap_prot = PROT_READ|PROT_WRITE;
u64 mmap_flags = MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE;
u64 stack_size = 0x10000;
void *stack_base = sys_mmap(0, stack_size, mmap_prot, mmap_flags, -1, 0);
if((i64)stack_base < 0) {
return _RT_ERROR_GENERIC;
}
void *stack = (u8*)stack_base + stack_size;
// Create the new thread
u64 flags = 0;
// flags |= CLONE_CHILD_CLEARTID;
// flags |= CLONE_PARENT_SETTID;
flags |= CLONE_FS;
flags |= CLONE_FILES;
flags |= CLONE_SIGHAND;
flags |= CLONE_THREAD;
flags |= CLONE_VM;
flags |= CLONE_SYSVSEM;
int *temp_permanent_storage = stack_base;
int *child_tid = &temp_permanent_storage[0];
int *parent_tid = &temp_permanent_storage[1];
*child_tid = 1;
*parent_tid = 0;
i64 ret = _cia_start_thread(flags, stack, parent_tid, child_tid, 0, thread_fn, ctx);
if(ret < 0) {
return _RT_ERROR_GENERIC;
}
return _RT_STATUS_OK;
}
static _RT_Status _rt_thread_join(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_detach(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_terminate(_RT_Thread *thread) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_sleep(u64 time) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_thread_get_timer_freq(u64 *freq) {
return _RT_ERROR_NOT_IMPLEMENTED;
}
static _RT_Status _rt_file_std_handles_init() {
_rt_file_stdin.fd = 0;
_rt_file_stdin.flags = _RT_FILE_READ;

View File

@ -1,6 +1,6 @@
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
_RT_Status status = _rt_thread_create(&thr->thread, (void (*)(void *))func, arg);
_RT_Status status = _rt_thread_create(&thr->thread, (int (*)(void *))func, arg);
if(status == _RT_STATUS_OK) {
return thrd_success;
}

View File

@ -57,7 +57,6 @@ int thrd_func(void *arg) {
print_int(counter);
print_char('\n');
cia_mutex_unlock(&g_print_mutex);
exit(1);
return 0;
}