mirror of https://github.com/flysand7/ciabatta.git
let the child threads get a dream stack too!
This commit is contained in:
parent
32f831bda3
commit
9fa3a65736
|
@ -43,6 +43,11 @@ _cia_start_thread:
|
||||||
pop rax ; thread_fn
|
pop rax ; thread_fn
|
||||||
pop rdi ; ctx
|
pop rdi ; ctx
|
||||||
call rax
|
call rax
|
||||||
|
; Make return value the first arg and call exit syscall
|
||||||
|
mov rdi, rax
|
||||||
|
mov rax, 60
|
||||||
|
syscall
|
||||||
|
; Just to be sure...
|
||||||
hlt
|
hlt
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
ret
|
||||||
|
|
4
cia.c
4
cia.c
|
@ -1,6 +1,10 @@
|
||||||
|
|
||||||
#include <cia/def.h>
|
#include <cia/def.h>
|
||||||
|
|
||||||
|
// Base includes
|
||||||
|
#include <cia/def.h>
|
||||||
|
#include <cia/internal.h>
|
||||||
|
|
||||||
// Platform-dependent sources
|
// Platform-dependent sources
|
||||||
#include _CIA_OS_CONF
|
#include _CIA_OS_CONF
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
extern _Thread_local int errno;
|
||||||
|
|
||||||
// errno-base.h
|
// errno-base.h
|
||||||
#define EPERM 1
|
#define EPERM 1
|
||||||
#define ENOENT 2
|
#define ENOENT 2
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct _RT_Thread {
|
||||||
void *handle;
|
void *handle;
|
||||||
};
|
};
|
||||||
static _RT_Status _rt_thread_current(_RT_Thread *thread);
|
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_join(_RT_Thread *thread);
|
||||||
static _RT_Status _rt_thread_detach(_RT_Thread *thread);
|
static _RT_Status _rt_thread_detach(_RT_Thread *thread);
|
||||||
static _RT_Status _rt_thread_terminate(_RT_Thread *thread);
|
static _RT_Status _rt_thread_terminate(_RT_Thread *thread);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <tinyrt.h>
|
#include <tinyrt.h>
|
||||||
#include "../os/linux/tinyrt.c"
|
#include "../os/linux/tinyrt.c"
|
||||||
|
|
||||||
|
#include <cia/internal.h>
|
||||||
|
|
||||||
#include <cia/mem.h>
|
#include <cia/mem.h>
|
||||||
#include "../src/cia-mem/util.c"
|
#include "../src/cia-mem/util.c"
|
||||||
#include "../src/cia-mem/allocator.c"
|
#include "../src/cia-mem/allocator.c"
|
||||||
|
@ -23,14 +25,6 @@
|
||||||
|
|
||||||
#include "stack.c"
|
#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 typedef Elf_Image;
|
||||||
struct Elf_Image {
|
struct Elf_Image {
|
||||||
Cia_Arena arena;
|
Cia_Arena arena;
|
||||||
|
@ -107,6 +101,7 @@ struct Stage3_Info_Struct {
|
||||||
Elf_Image *ldso;
|
Elf_Image *ldso;
|
||||||
void *stack_base;
|
void *stack_base;
|
||||||
u64 stack_size;
|
u64 stack_size;
|
||||||
|
void *tls_image;
|
||||||
u64 tls_size;
|
u64 tls_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -356,7 +351,7 @@ static void ld_stage3_entry(u64 has_new_stack, void *ctx) {
|
||||||
Stage3_Info_Struct *info = ctx;
|
Stage3_Info_Struct *info = ctx;
|
||||||
_dbg_printf("Stack: %x-%x\n", info->stack_base, (u8 *)info->stack_base+info->stack_size);
|
_dbg_printf("Stack: %x-%x\n", info->stack_base, (u8 *)info->stack_base+info->stack_size);
|
||||||
// Set up the thread control block
|
// 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->thread_id = 0;
|
||||||
tcb->stack_canary = 0x12345678fedcba98;
|
tcb->stack_canary = 0x12345678fedcba98;
|
||||||
// Copy TLS initialization image below TCB
|
// 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) {
|
for(int i = 0; i < tls_image_size; ++i) {
|
||||||
tls_image[i] = tls_image_base[i];
|
tls_image[i] = tls_image_base[i];
|
||||||
}
|
}
|
||||||
|
info->tls_image = tls_image_base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set up the thread pointer
|
// Set up the thread pointer
|
||||||
|
@ -386,6 +382,10 @@ static void ld_stage3_entry(u64 has_new_stack, void *ctx) {
|
||||||
sys_exit(1);
|
sys_exit(1);
|
||||||
}
|
}
|
||||||
_dbg_printf("Entered loader stage 3. Entering main executable\n");
|
_dbg_printf("Entered loader stage 3. Entering main executable\n");
|
||||||
void (*crt_entry)() = elf_addr(info->app, ((Elf64_Ehdr *)info->app->base)->e_entry);
|
Cia_CRT_Params params;
|
||||||
crt_entry();
|
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(¶ms);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
static u64 cia_stack_size;
|
||||||
|
static u64 cia_tls_image_size;
|
||||||
|
static void *cia_tls_image_base;
|
||||||
|
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -9,4 +13,5 @@
|
||||||
#include "entry.c"
|
#include "entry.c"
|
||||||
#include <tinyrt.h>
|
#include <tinyrt.h>
|
||||||
#include "tinyrt.c"
|
#include "tinyrt.c"
|
||||||
|
#include "tinyrt-threads.c"
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@ void __stack_chk_fail(void) {
|
||||||
extern int main(int argc, char **argv, char **envp);
|
extern int main(int argc, char **argv, char **envp);
|
||||||
static void _fileapi_init();
|
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
|
// Get the envp
|
||||||
// char **envp = argv + (argc + 1);
|
// char **envp = argv + (argc + 1);
|
||||||
// init(argc, argv, envp);
|
// init(argc, argv, envp);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,76 +1,10 @@
|
||||||
|
|
||||||
// See src/tinyrt.h file for the interface this file implements
|
// 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) {
|
_Noreturn static void _rt_program_exit(int code) {
|
||||||
sys_exit(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() {
|
static _RT_Status _rt_file_std_handles_init() {
|
||||||
_rt_file_stdin.fd = 0;
|
_rt_file_stdin.fd = 0;
|
||||||
_rt_file_stdin.flags = _RT_FILE_READ;
|
_rt_file_stdin.flags = _RT_FILE_READ;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
|
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) {
|
if(status == _RT_STATUS_OK) {
|
||||||
return thrd_success;
|
return thrd_success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ int thrd_func(void *arg) {
|
||||||
print_int(counter);
|
print_int(counter);
|
||||||
print_char('\n');
|
print_char('\n');
|
||||||
cia_mutex_unlock(&g_print_mutex);
|
cia_mutex_unlock(&g_print_mutex);
|
||||||
exit(1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue