Linux threads (not working)

This commit is contained in:
flysand7 2023-08-15 19:54:02 +11:00
parent 1beb40051e
commit 82788654d8
12 changed files with 200 additions and 13 deletions

View File

@ -161,7 +161,10 @@ try:
print(colors.red, f" ERROR: library config doesn't contain configuration for platform {target}", colors.reset, sep='')
for include in platform_config['includes']:
include_path = platform_config['path']
ciabatta_header.write(f'#include "{include_path}/{include}"\n')
ciabatta_header.write(f'#include <{include}>\n')
for source in platform_config['sources']:
source_path = platform_config['path']
ciabatta_header.write(f'#include "{source_path}/{source}"\n')
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
ciabatta_header.write(f'#include <tinyrt.h>\n')
for tinyrt_source in platform_config['tinyrt']:

View File

@ -32,7 +32,7 @@ _Noreturn void abort(void) {
}
_Noreturn void exit(int code) {
for(u64 i = n_atexit_handlers-1; i-- != 0; ) {
for(i64 i = n_atexit_handlers-1; i-- > 0; ) {
void (*handler)(void) = atexit_handlers[i];
handler();
}
@ -48,7 +48,7 @@ _Noreturn void _Exit(int code) {
}
_Noreturn void quick_exit(int code) {
for(u64 i = n_at_quick_exit_handlers-1; i-- != 0; ) {
for(i64 i = n_at_quick_exit_handlers-1; i-- > 0; ) {
void (*handler)(void) = at_quick_exit_handlers[i];
handler();
}

View File

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

37
src/include/linux/sched.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#define CLONE_NEWTIME 0x00000080
#define CLONE_VM 0x00000100
#define CLONE_FS 0x00000200
#define CLONE_FILES 0x00000400
#define CLONE_SIGHAND 0x00000800
#define CLONE_PIDFD 0x00001000
#define CLONE_PTRACE 0x00002000
#define CLONE_VFORK 0x00004000
#define CLONE_PARENT 0x00008000
#define CLONE_THREAD 0x00010000
#define CLONE_NEWNS 0x00020000
#define CLONE_SYSVSEM 0x00040000
#define CLONE_SETTLS 0x00080000
#define CLONE_PARENT_SETTID 0x00100000
#define CLONE_CHILD_CLEARTID 0x00200000
#define CLONE_DETACHED 0x00400000
#define CLONE_UNTRACED 0x00800000
#define CLONE_CHILD_SETTID 0x01000000
#define CLONE_NEWCGROUP 0x02000000
#define CLONE_NEWUTS 0x04000000
#define CLONE_NEWIPC 0x08000000
#define CLONE_NEWUSER 0x10000000
#define CLONE_NEWPID 0x20000000
#define CLONE_NEWNET 0x40000000
#define CLONE_IO 0x80000000
#define SCHED_OTHER 0
#define SCHED_FIFO 1
#define SCHED_RR 2
#define SCHED_BATCH 3
#define SCHED_ISO 4
#define SCHED_IDLE 5
#define SCHED_DEADLINE 6
#define SCHED_RESET_ON_FORK 0x40000000

19
src/include/threads.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
typedef int (*thrd_start_t)(void *);
struct thrd_t typedef thrd_t;
struct thrd_t {
_RT_Thread thread;
};
enum {
thrd_success = 0,
thrd_nomem = -1,
thrd_timedout = -2,
thrd_busy = -3,
thrd_error = -4
};
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);

View File

@ -45,6 +45,22 @@ static _RT_Status _rt_deinit();
_Noreturn static void _rt_program_exit(int code);
#endif
// Thread API
struct _RT_Thread typedef _RT_Thread;
struct _RT_Thread {
u64 tid;
void *handle;
};
#if _RT_API_THREAD == 1
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_join(_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_sleep(u64 time);
static _RT_Status _rt_thread_get_timer_freq(u64 *freq);
#endif
// Environment API
#if _RT_API_ENVIRONMENT == 1
static _RT_Status _rt_shell_exec(char const *cmd);

View File

@ -24,6 +24,7 @@
includes: [
"stdlib.h",
"stdio.h",
"threads.h",
"cia-mem.h",
],
@ -32,10 +33,13 @@ platforms: [
name: "linux",
path: "linux",
includes: [
"entry.c",
"sys/mman.h",
"errno.h",
"mman.h",
"fcntl.h"
"fcntl.h",
"sched.h",
],
sources: [
"entry.c",
],
tinyrt: [
"tinyrt.c"
@ -44,7 +48,7 @@ platforms: [
{
name: "windows",
path: "windows",
includes: [
sources: [
"windows.c"
],
tinyrt: [
@ -79,6 +83,16 @@ apis: [
"cia_memory",
]
},
{
name: "stdlib_threads",
path: "impl/stdlib-thread",
includes: [
"thread.c",
],
reqs: [
"rt_api_thread"
]
},
{
name: "stdlib_file",
path: "impl/stdlib-file",
@ -100,4 +114,5 @@ export: [
"cia_memory",
"stdlib_program",
"stdlib_file",
"stdlib_threads",
]

View File

@ -1,6 +1,68 @@
// See src/tinyrt.h file for the interface this file implements
_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;
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;
}
u64 *stack = (void *)((u8 *)stack_base + stack_size);
stack[-1] = (u64)&&thread_return;
stack[-2] = 0;
// 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;
int parent_tid = 0;
int child_tid = 0;
i64 cur_tid = sys_clone(flags, &stack[-2], &parent_tid, &child_tid, 0);
thread_return:
if(cur_tid < 0) {
return _RT_ERROR_GENERIC;
}
if(cur_tid == child_tid) {
thread_fn(ctx);
}
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;
@ -65,10 +127,6 @@ static _RT_Status _rt_file_close(_RT_File *file) {
return _RT_STATUS_OK;
}
_Noreturn static void _rt_program_exit(int code) {
sys_exit(code);
}
static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 size, void **out_addr) {
void *addr = sys_mmap((u64)optional_desired_addr, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(addr == NULL) {
@ -84,5 +142,4 @@ static _RT_Status _rt_mem_free(void *ptr, u64 len) {
return _RT_ERROR_GENERIC;
}
return _RT_STATUS_OK;
}
}

View File

@ -8,3 +8,4 @@ rt_api_file: true,
rt_api_program: true,
rt_api_shell: false,
rt_api_memory: true,
rt_api_thread: true,

View File

@ -6,6 +6,7 @@
#include "loader.h"
#include <sys/mman.h>
#include <sched.h>
#include <errno.h>
#include <fcntl.h>
#include "../linux/tinyrt-iface.h"

8
test.c Normal file
View File

@ -0,0 +1,8 @@
#define __USE_GNU
#include <sched.h>
#ifdef CLONE_FILES
#define MYMACRO 1
#endif

22
tests/threaded.c Normal file
View File

@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
int thrd_func(void *arg) {
char string[] = "child thread: ok!\n";
fwrite(string, 1, sizeof string-1, stdout);
// exit(1);
for(;;);
return 0;
}
int main() {
{char string[] = "main thred: before\n";
fwrite(string, 1, sizeof string-1, stdout);}
thrd_t thrd;
thrd_create(&thrd, thrd_func, NULL);
{char string[] = "main thread: after!\n";
fwrite(string, 1, sizeof string-1, stdout);}
return 0;
}