mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
add TLS and rudimental pthread support into the libos version
This commit is contained in:
parent
600425c57e
commit
1dce82e27d
8 changed files with 66 additions and 30 deletions
|
@ -67,6 +67,7 @@ static inline void enter_user_task(size_t ep, size_t stack)
|
|||
static int thread_entry(void* arg, size_t ep)
|
||||
{
|
||||
task_t* curr_task = per_core(current_task);
|
||||
#if 0
|
||||
size_t addr, stack = 0;
|
||||
size_t flags;
|
||||
int64_t npages;
|
||||
|
@ -99,27 +100,29 @@ static int thread_entry(void* arg, size_t ep)
|
|||
// create vma regions for the user-level stack
|
||||
flags = VMA_CACHEABLE|VMA_USER|VMA_READ|VMA_WRITE;
|
||||
vma_add(stack, stack+npages*PAGE_SIZE-1, flags);
|
||||
#endif
|
||||
|
||||
//vma_dump();
|
||||
|
||||
// do we have to create a TLS segement?
|
||||
if (curr_task->tls_addr && curr_task->tls_mem_size) {
|
||||
// set fs register to the TLS segment
|
||||
writefs(stack+offset);
|
||||
kprintf("Task %d set fs to 0x%llx\n", curr_task->id, stack+offset);
|
||||
if (curr_task->tls_addr && curr_task->tls_size) {
|
||||
char* tls_addr = NULL;
|
||||
|
||||
tls_addr = kmalloc(curr_task->tls_size);
|
||||
// copy default TLS segment to stack
|
||||
offset -= curr_task->tls_mem_size;
|
||||
if (curr_task->tls_file_size)
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size);
|
||||
memcpy((void*) (tls_addr), (void*) curr_task->tls_addr, curr_task->tls_size);
|
||||
|
||||
// align stack to 16 byte boundary
|
||||
offset = offset & ~0xFULL;
|
||||
// set fs register to the TLS segment
|
||||
writefs((size_t) tls_addr);
|
||||
kprintf("Task %d set fs to %p\n", curr_task->id, tls_addr);
|
||||
} else writefs(0); // no TLS => clear fs register
|
||||
|
||||
// set first argument
|
||||
asm volatile ("mov %0, %%rdi" :: "r"(arg));
|
||||
enter_user_task(ep, stack+offset);
|
||||
//asm volatile ("mov %0, %%rdi" :: "r"(arg));
|
||||
//enter_user_task(ep, stack+offset);
|
||||
|
||||
entry_point_t call_ep = (entry_point_t) ep;
|
||||
call_ep(arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -182,12 +185,12 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
|
|||
|
||||
/* The instruction pointer shall be set on the first function to be called
|
||||
after IRETing */
|
||||
if ((size_t) ep < KERNEL_SPACE) {
|
||||
stptr->rip = (size_t)ep;
|
||||
} else {
|
||||
//if ((size_t) ep < KERNEL_SPACE) {
|
||||
// stptr->rip = (size_t)ep;
|
||||
//} else {
|
||||
stptr->rip = (size_t)thread_entry;
|
||||
stptr->rsi = (size_t)ep; // use second argument to transfer the entry point
|
||||
}
|
||||
//}
|
||||
stptr->cs = 0x08;
|
||||
stptr->ss = 0x10;
|
||||
stptr->gs = core_id * ((size_t) &percore_end0 - (size_t) &percore_start);
|
||||
|
@ -359,9 +362,11 @@ static int load_task(load_args_t* largs)
|
|||
break;
|
||||
case ELF_PT_TLS:
|
||||
kprintf("Found TLS segment. addr 0x%llx, mem size 0x%llx, file size 0x%llx\n", prog_header.virt_addr, prog_header.mem_size, prog_header.file_size);
|
||||
#if 0
|
||||
curr_task->tls_addr = prog_header.virt_addr;
|
||||
curr_task->tls_mem_size = prog_header.mem_size;
|
||||
curr_task->tls_file_size = prog_header.file_size;
|
||||
#endif
|
||||
break;
|
||||
case ELF_PT_NOTE:
|
||||
//kprintf("Found note segment: %s\n", (char*)prog_header.virt_addr + 12);
|
||||
|
@ -401,6 +406,7 @@ static int load_task(load_args_t* largs)
|
|||
|
||||
offset = DEFAULT_STACK_SIZE-16;
|
||||
|
||||
#if 0
|
||||
// do we have to create a TLS segement?
|
||||
if (curr_task->tls_addr && curr_task->tls_mem_size) {
|
||||
if (curr_task->tls_mem_size >= DEFAULT_STACK_SIZE-128) {
|
||||
|
@ -418,6 +424,7 @@ static int load_task(load_args_t* largs)
|
|||
if (curr_task->tls_file_size)
|
||||
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
// push strings on the stack
|
||||
memset((void*) (stack+offset), 0, 4);
|
||||
|
|
|
@ -108,10 +108,8 @@ typedef struct task {
|
|||
struct task* prev;
|
||||
/// TLS address
|
||||
size_t tls_addr;
|
||||
/// TLS mem size
|
||||
size_t tls_mem_size;
|
||||
/// TLS file size
|
||||
size_t tls_file_size;
|
||||
size_t tls_size;
|
||||
/// LwIP error code
|
||||
int lwip_err;
|
||||
/// FPU state
|
||||
|
|
|
@ -68,6 +68,8 @@ extern const void kernel_start;
|
|||
extern const void kernel_end;
|
||||
extern const void kbss_start;
|
||||
extern const void kbss_end;
|
||||
extern const void tls_start;
|
||||
extern const void tls_end;
|
||||
extern const void percore_start;
|
||||
extern const void percore_end0;
|
||||
extern const void percore_end;
|
||||
|
@ -270,6 +272,28 @@ static int initd(void* arg)
|
|||
|
||||
init_netifs();
|
||||
|
||||
// do we have a thread local storage?
|
||||
if (((size_t) &tls_end - (size_t) &tls_start) > 0) {
|
||||
char* tls_addr = NULL;
|
||||
|
||||
curr_task->tls_addr = (size_t) &tls_start;
|
||||
curr_task->tls_size = (size_t) &tls_end - (size_t) &tls_start;
|
||||
|
||||
// TODO: free TLS after termination
|
||||
tls_addr = kmalloc(curr_task->tls_size);
|
||||
if (BUILTIN_EXPECT(!tls_addr, 0)) {
|
||||
kprintf("load_task: heap is missing!\n");
|
||||
kfree(curr_task->heap);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy((void*) tls_addr, (void*) curr_task->tls_addr, curr_task->tls_size);
|
||||
|
||||
// set fs register to the TLS segment
|
||||
writefs((size_t) tls_addr);
|
||||
kprintf("Task %d set fs to 0x%zx\n", curr_task->id, tls_addr);
|
||||
} else writefs(0); // no TLS => clear fs register
|
||||
|
||||
//init_rcce();
|
||||
|
||||
s = socket(PF_INET , SOCK_STREAM , 0);
|
||||
|
@ -386,6 +410,7 @@ int hermit_main(void)
|
|||
kprintf("This is Hermit %s, build date %u\n", VERSION, &__DATE__);
|
||||
kprintf("Isle %d of %d possible isles\n", isle, possible_isles);
|
||||
kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end);
|
||||
kprintf("TLS image starts at %p and ends at %p\n", &tls_start, &tls_end);
|
||||
kprintf("Per core data starts at %p and ends at %p\n", &percore_start, &percore_end);
|
||||
kprintf("Per core size 0x%zd\n", (size_t) &percore_end0 - (size_t) &percore_start);
|
||||
kprintf("Processor frequency: %u MHz\n", get_cpu_frequency());
|
||||
|
|
|
@ -61,6 +61,11 @@ int sys_getprio(void)
|
|||
return task->prio;
|
||||
}
|
||||
|
||||
int sys_setprio(tid_t* id, int prio)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static void sys_yield(void)
|
||||
{
|
||||
reschedule();
|
||||
|
@ -357,6 +362,11 @@ int sys_sem_timedwait(sem_t *sem, unsigned int ms)
|
|||
return sem_wait(sem, ms);
|
||||
}
|
||||
|
||||
int sys_sem_cancelablewait(sem_t* sem, unsigned int ms)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int sys_clone(tid_t* id, void* ep, void* argv)
|
||||
{
|
||||
return clone_task(id, ep, argv, per_core(current_task)->prio);
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
* A task's id will be its position in this array.
|
||||
*/
|
||||
static task_t task_table[MAX_TASKS] = { \
|
||||
[0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}};
|
||||
[0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0}};
|
||||
|
||||
static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT;
|
||||
|
||||
|
@ -294,8 +294,6 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
return -EINVAL;
|
||||
if (BUILTIN_EXPECT(prio > MAX_PRIO, 0))
|
||||
return -EINVAL;
|
||||
if (BUILTIN_EXPECT((size_t)ep < KERNEL_SPACE, 0))
|
||||
return -EINVAL;
|
||||
|
||||
curr_task = per_core(current_task);
|
||||
|
||||
|
@ -324,8 +322,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
task_table[i].start_tick = get_clock_tick();
|
||||
task_table[i].parent = curr_task->id;
|
||||
task_table[i].tls_addr = curr_task->tls_addr;
|
||||
task_table[i].tls_mem_size = curr_task->tls_mem_size;
|
||||
task_table[i].tls_file_size = curr_task->tls_file_size;
|
||||
task_table[i].tls_size = curr_task->tls_size;
|
||||
task_table[i].lwip_err = 0;
|
||||
task_table[i].user_usage = curr_task->user_usage;
|
||||
task_table[i].page_map = curr_task->page_map;
|
||||
|
@ -411,8 +408,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
|
|||
task_table[i].start_tick = get_clock_tick();
|
||||
task_table[i].parent = 0;
|
||||
task_table[i].tls_addr = 0;
|
||||
task_table[i].tls_mem_size = 0;
|
||||
task_table[i].tls_file_size = 0;
|
||||
task_table[i].tls_size = 0;
|
||||
task_table[i].lwip_err = 0;
|
||||
|
||||
spinlock_irqsave_init(&task_table[i].page_lock);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 72df72547e5f46d4413f101abd8979d03e8e44d3
|
||||
Subproject commit 8931334f7f4e24b40c0973753e410421f0733a80
|
|
@ -1 +1 @@
|
|||
Subproject commit 53835aebf4adb9b9582a3fa0665d5340568208c8
|
||||
Subproject commit a7188dcfd4e33dc2a1b4902c58c44574cebf5fe4
|
|
@ -3,7 +3,7 @@ TARGET=x86_64-hermit
|
|||
MAKE = make
|
||||
override STRIP_DEBUG = --strip-debug #--strip-unneeded
|
||||
KEEP_DEBUG = --only-keep-debug
|
||||
OBJCOPY_FLAGS = -j .mboot -j .ktext -j .kdata -j .kbss -j .fini -j .init -j .ctors -j .dtors -j .text -j .data -j .rodata -j .bss -j .percore -O binary
|
||||
OBJCOPY_FLAGS = -j .mboot -j .ktext -j .kdata -j .kbss -j .tbss -j .tdata -j .fini -j .init -j .ctors -j .dtors -j .text -j .data -j .rodata -j .bss -j .percore -O binary
|
||||
|
||||
# Set your own cross compiler tool chain prefix here
|
||||
CROSSCOMPREFIX = x86_64-hermit-
|
||||
|
@ -44,7 +44,7 @@ endif
|
|||
|
||||
default: all
|
||||
|
||||
all: hello.bin hello++.bin #hellof.bin thr_hello.bin #jacobi RCCE_minimum
|
||||
all: hello.bin hello++.bin thr_hello.bin #hellof.bin #jacobi RCCE_minimum
|
||||
|
||||
hello++: hello++.o
|
||||
@echo [LD] $@
|
||||
|
|
Loading…
Add table
Reference in a new issue