1
0
Fork 0
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:
Stefan Lankes 2015-12-30 02:17:23 +01:00
parent 600425c57e
commit 1dce82e27d
8 changed files with 66 additions and 30 deletions

View file

@ -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);

View file

@ -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

View file

@ -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());

View file

@ -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);

View file

@ -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

View file

@ -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] $@