mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
fix TLS initialization, disable the support of contiguous blocks
- fix TLS initialization on aarch64 - disable temporary the support of contiguous blocks on aarch64 - add possibility to dump a page table entries - improve TLS test case
This commit is contained in:
parent
33060c13f1
commit
63bd7fa8b4
13 changed files with 192 additions and 101 deletions
|
@ -240,4 +240,8 @@ static inline void tlb_flush_range(size_t start, size_t end)
|
|||
asm volatile ("isb" ::: "memory");
|
||||
}
|
||||
|
||||
/** @brief Print the current page table tree
|
||||
*/
|
||||
void page_dump(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -90,6 +90,13 @@ static inline uint32_t get_sctlr(void)
|
|||
return status;
|
||||
}
|
||||
|
||||
static inline uint64_t get_elr(void)
|
||||
{
|
||||
uint64_t ret;
|
||||
asm volatile("mrs %0, elr_el1" : "=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @brief get the current exception level
|
||||
*
|
||||
* Helper function to get the current exception level
|
||||
|
@ -102,30 +109,16 @@ static inline uint32_t get_current_el(void)
|
|||
return (curr>>2) & 0x3;
|
||||
}
|
||||
|
||||
/** @brief Get thread local storage
|
||||
*
|
||||
* Helper function to get the TLS of the current task
|
||||
*/
|
||||
static inline size_t get_tls(void) {
|
||||
uint64_t addr = 0;
|
||||
asm volatile(
|
||||
"mrs %0, tpidr_el0"
|
||||
: "+r"(addr)
|
||||
:
|
||||
: );
|
||||
/** @brief Get thread id register */
|
||||
static inline size_t get_tpidr(void) {
|
||||
uint64_t addr;
|
||||
asm volatile("mrs %0, tpidr_el0" : "=r"(addr));
|
||||
return addr;
|
||||
}
|
||||
|
||||
/** @brief Set thread local storage
|
||||
*
|
||||
* Helper function to set the TLS of the current task
|
||||
*/
|
||||
static inline void set_tls(size_t addr) {
|
||||
asm volatile(
|
||||
"msr tpidr_el0, %0"
|
||||
: "=r"(addr)
|
||||
:
|
||||
: );
|
||||
/** @brief Set thread id register */
|
||||
static inline void set_tpidr(size_t addr) {
|
||||
asm volatile("msr tpidr_el0, %0" :: "r"(addr));
|
||||
}
|
||||
|
||||
/** @brief Read id_aa64mmfr0_el1 register
|
||||
|
@ -188,7 +181,7 @@ static inline void write_mair(size_t val) {
|
|||
/** @brief Read ttbr0_el1 register
|
||||
* @return ttbr0_el1's value
|
||||
*/
|
||||
static inline size_t read_ttbr0(void) {
|
||||
static inline size_t get_ttbr0(void) {
|
||||
size_t val;
|
||||
asm volatile("mrs %0, ttbr0_el1" : "=r"(val) :: "memory");
|
||||
return val;
|
||||
|
@ -197,14 +190,14 @@ static inline size_t read_ttbr0(void) {
|
|||
/** @brief Write a value into ttbr0_el1 register
|
||||
* @param val The value you want to write into ttbr0_el1
|
||||
*/
|
||||
static inline void write_ttbr0(size_t val) {
|
||||
static inline void set_ttbr0(size_t val) {
|
||||
asm volatile("msr ttbr0_el1, %0" :: "r"(val) : "memory");
|
||||
}
|
||||
|
||||
/** @brief Read ttbr1_el1 register
|
||||
* @return ttbr1_el1's value
|
||||
*/
|
||||
static inline size_t read_ttbr1(void) {
|
||||
static inline size_t get_ttbr1(void) {
|
||||
size_t val;
|
||||
asm volatile("mrs %0, ttbr1_el1" : "=r"(val) :: "memory");
|
||||
return val;
|
||||
|
@ -213,7 +206,7 @@ static inline size_t read_ttbr1(void) {
|
|||
/** @brief Write a value into ttbr1_el1 register
|
||||
* @param val The value you want to write into ttbr1_el1
|
||||
*/
|
||||
static inline void write_ttbr1(size_t val) {
|
||||
static inline void set_ttbr1(size_t val) {
|
||||
asm volatile("msr ttbr1_el1, %0" :: "r"(val) : "memory");
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef wchar_t wint_t;
|
|||
struct state {
|
||||
uint64_t elr_el1;
|
||||
uint64_t spsr_el1;
|
||||
uint64_t res;
|
||||
uint64_t tpidr_el0;
|
||||
uint64_t x0;
|
||||
uint64_t x1;
|
||||
uint64_t x2;
|
||||
|
|
|
@ -377,7 +377,9 @@ ldr \xreg, [sp], #8
|
|||
stp x5, x6, [sp, #-16]!
|
||||
stp x3, x4, [sp, #-16]!
|
||||
stp x1, x2, [sp, #-16]!
|
||||
str x0, [sp, #-16]!
|
||||
|
||||
mrs x22, tpidr_el0
|
||||
stp x0, x22, [sp, #-16]!
|
||||
|
||||
mrs x22, elr_el1
|
||||
mrs x23, spsr_el1
|
||||
|
@ -389,7 +391,9 @@ ldr \xreg, [sp], #8
|
|||
msr elr_el1, x22
|
||||
msr spsr_el1, x23
|
||||
|
||||
ldr x0, [sp], #16
|
||||
ldp x0, x22, [sp], #16
|
||||
msr tpidr_el0, x22
|
||||
|
||||
ldp x1, x2, [sp], #16
|
||||
ldp x3, x4, [sp], #16
|
||||
ldp x5, x6, [sp], #16
|
||||
|
|
|
@ -286,6 +286,10 @@ void do_sync(void *regs)
|
|||
return;
|
||||
|
||||
LOG_ERROR("Unable to handle page fault at 0x%llx\n", far);
|
||||
LOG_ERROR("Exception return address 0x%llx\n", get_elr());
|
||||
LOG_ERROR("Thread ID register 0x%llx\n", get_tpidr());
|
||||
LOG_ERROR("Table Base Register 0x%llx\n", get_ttbr0());
|
||||
LOG_ERROR("Exception Syndrome Register 0x%lx\n", esr);
|
||||
|
||||
// send EOI
|
||||
gicc_write(GICC_EOIR, iar);
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
#include <hermit/logging.h>
|
||||
#include <hermit/string.h>
|
||||
|
||||
#define TLS_ALIGNBITS 5
|
||||
#define TLS_ALIGNSIZE (1L << TLS_ALIGNBITS)
|
||||
#define TSL_ALIGNMASK ((~0L) << TLS_ALIGNBITS)
|
||||
#define TLS_FLOOR(addr) ((((size_t)addr) + TLS_ALIGNSIZE - 1) & TSL_ALIGNMASK)
|
||||
|
||||
extern int smp_main(void);
|
||||
|
||||
/*
|
||||
|
@ -45,12 +40,24 @@ extern int smp_main(void);
|
|||
*/
|
||||
extern const void tls_start;
|
||||
extern const void tls_end;
|
||||
extern const void tdata_end;
|
||||
|
||||
extern atomic_int32_t cpu_online;
|
||||
extern atomic_int32_t current_boot_id;
|
||||
|
||||
static char tls[16][DEFAULT_STACK_SIZE];
|
||||
static int id = 0;
|
||||
typedef union dtv
|
||||
{
|
||||
size_t counter;
|
||||
struct {
|
||||
void *val;
|
||||
uint8_t is_static;
|
||||
} pointer;
|
||||
} dtv_t;
|
||||
|
||||
typedef struct {
|
||||
dtv_t *dtv; /* dtv */
|
||||
void *privat; /* private */
|
||||
} thread_block_t;
|
||||
|
||||
static int init_tls(void)
|
||||
{
|
||||
|
@ -58,33 +65,35 @@ static int init_tls(void)
|
|||
|
||||
// do we have a thread local storage?
|
||||
if (((size_t) &tls_end - (size_t) &tls_start) > 0) {
|
||||
char* tls_addr = NULL;
|
||||
size_t tpidr_el0;
|
||||
size_t tdata_size = (size_t) &tdata_end - (size_t) &tls_start;
|
||||
|
||||
curr_task->tls_addr = (size_t) &tls_start;
|
||||
curr_task->tls_size = (size_t) &tls_end - (size_t) &tls_start;
|
||||
|
||||
//tls_addr = kmalloc(curr_task->tls_size + TLS_ALIGNSIZE + sizeof(size_t));
|
||||
tls_addr = tls[id];
|
||||
id++;
|
||||
if (BUILTIN_EXPECT(!tls_addr, 0)) {
|
||||
thread_block_t* tcb = (thread_block_t*) kmalloc(curr_task->tls_size+sizeof(thread_block_t));
|
||||
if (BUILTIN_EXPECT(!tcb, 0)) {
|
||||
LOG_ERROR("load_task: heap is missing!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(tls_addr, 0x00, TLS_ALIGNSIZE);
|
||||
memcpy((void*) TLS_FLOOR(tls_addr), (void*) curr_task->tls_addr, curr_task->tls_size);
|
||||
tpidr_el0 = (size_t) TLS_FLOOR(tls_addr) + curr_task->tls_size;
|
||||
*((size_t*)tpidr_el0) = tpidr_el0;
|
||||
memset((void*) tcb, 0x00, curr_task->tls_size+sizeof(thread_block_t));
|
||||
tcb->dtv = (dtv_t*) &tcb[1];
|
||||
memcpy((char*) tcb->dtv, (void*) curr_task->tls_addr, tdata_size);
|
||||
|
||||
// set tpidr_el0 register to the TLS segment
|
||||
set_tls(tpidr_el0);
|
||||
//LOG_INFO("TLS of task %d on core %d starts at 0x%zx (size 0x%zx)\n", curr_task->id, CORE_ID, TLS_FLOOR(tls_addr), curr_task->tls_size);
|
||||
} else set_tls(0); // no TLS => clear tpidr_el0 register
|
||||
set_tpidr((size_t) tcb);
|
||||
LOG_INFO("TLS of task %d on core %d starts at 0x%zx (tls size 0x%zx)\n", curr_task->id, CORE_ID, get_tpidr(), curr_task->tls_size);
|
||||
} else set_tpidr(0); // no TLS => clear tpidr_el0 register
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void destroy_tls(void)
|
||||
{
|
||||
size_t tpidr = get_tpidr();
|
||||
if (tpidr)
|
||||
kfree((void*)tpidr);
|
||||
}
|
||||
|
||||
static int thread_entry(void* arg, size_t ep)
|
||||
{
|
||||
|
||||
|
@ -213,11 +222,3 @@ const int32_t is_uhyve(void)
|
|||
{
|
||||
return (uhyve != 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
extern uint32_t single_kernel;
|
||||
const int32_t is_single_kernel(void)
|
||||
{
|
||||
return (single_kernel != 0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -91,8 +91,8 @@ int page_set_flags(size_t viraddr, uint32_t npages, int flags)
|
|||
int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
||||
{
|
||||
int lvl, ret = -ENOMEM;
|
||||
long vpn = viraddr >> PAGE_BITS;
|
||||
long first[PAGE_LEVELS], last[PAGE_LEVELS];
|
||||
ssize_t vpn = viraddr >> PAGE_BITS;
|
||||
ssize_t first[PAGE_LEVELS], last[PAGE_LEVELS];
|
||||
size_t page_counter = 0;
|
||||
size_t cflags = 0;
|
||||
|
||||
|
@ -122,7 +122,7 @@ int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
|||
self[lvl][vpn] = phyaddr | PT_PT;
|
||||
|
||||
/* Fill new table with zeros */
|
||||
//LOG_INFO("Clear new page table at %p\n", &self[lvl-1][vpn<<PAGE_MAP_BITS]);
|
||||
//LOG_INFO("Clear new page table at %p for 0x%zx, %d\n", &self[lvl-1][vpn<<PAGE_MAP_BITS], viraddr, lvl-1);
|
||||
tlb_flush_range((size_t) (&self[lvl-1][vpn<<PAGE_MAP_BITS]),
|
||||
((size_t)(&self[lvl-1][vpn<<PAGE_MAP_BITS]))+PAGE_SIZE);
|
||||
memset(&self[lvl-1][vpn<<PAGE_MAP_BITS], 0, PAGE_SIZE);
|
||||
|
@ -132,10 +132,12 @@ int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
|||
kprintf("Remap address 0x%zx at core %d\n", viraddr, CORE_ID);
|
||||
}*/
|
||||
|
||||
#if 0
|
||||
if (!cflags && !(viraddr & 0XFFFFULL) && (npages-page_counter >= 16))
|
||||
cflags = PT_CONTIG;
|
||||
else if (cflags && !(viraddr & 0xFFFFULL) && (npages-page_counter < 16))
|
||||
cflags = 0;
|
||||
#endif
|
||||
|
||||
if (bits & PG_DEVICE)
|
||||
self[lvl][vpn] = phyaddr | PT_DEVICE | cflags;
|
||||
|
@ -195,8 +197,8 @@ int page_fault_handler(size_t viraddr)
|
|||
int check_pagetables(size_t vaddr)
|
||||
{
|
||||
int lvl;
|
||||
long vpn = vaddr >> PAGE_BITS;
|
||||
long index[PAGE_LEVELS];
|
||||
ssize_t vpn = vaddr >> PAGE_BITS;
|
||||
ssize_t index[PAGE_LEVELS];
|
||||
|
||||
/* Calculate index boundaries for page map traversal */
|
||||
for (lvl=0; lvl<PAGE_LEVELS; lvl++)
|
||||
|
@ -215,10 +217,9 @@ int page_fault_handler(size_t viraddr)
|
|||
|
||||
spinlock_irqsave_lock(&page_lock);
|
||||
|
||||
if ((task->heap) && (viraddr >= task->heap->start) && (viraddr < task->heap->end)) {
|
||||
size_t flags;
|
||||
int ret;
|
||||
//page_dump();
|
||||
|
||||
if ((task->heap) && (viraddr >= task->heap->start) && (viraddr < task->heap->end)) {
|
||||
/*
|
||||
* do we have a valid page table entry? => flush TLB and return
|
||||
*/
|
||||
|
@ -237,8 +238,8 @@ int page_fault_handler(size_t viraddr)
|
|||
goto default_handler;
|
||||
}
|
||||
|
||||
flags = PG_USER|PG_RW;
|
||||
ret = __page_map(viraddr, phyaddr, 1, flags);
|
||||
size_t flags = PG_USER|PG_RW;
|
||||
int ret = __page_map(viraddr, phyaddr, 1, flags);
|
||||
|
||||
if (BUILTIN_EXPECT(ret, 0)) {
|
||||
LOG_ERROR("map_region: could not map %#lx to %#lx, task = %u\n", phyaddr, viraddr, task->id);
|
||||
|
@ -261,24 +262,98 @@ default_handler:
|
|||
// weak symbol is used to detect a Go application
|
||||
void __attribute__((weak)) runtime_osinit();
|
||||
|
||||
/*static void dump_pgtable(void)
|
||||
typedef size_t page_entry_t;
|
||||
|
||||
/** @brief Get the corresponding virtual address to a page map entry */
|
||||
static inline size_t entry_to_virt(page_entry_t* entry, int level)
|
||||
{
|
||||
size_t* l0 = &l0_pgtable;
|
||||
size_t addr = (size_t) entry;
|
||||
|
||||
LOG_INFO("Dump page table tree: %p\n", l0);
|
||||
addr <<= (level+1) * PAGE_MAP_BITS;
|
||||
addr &= 0x0000FFFFFFFFFFFFULL;
|
||||
|
||||
for (int i=0; i<512; i++) {
|
||||
if (l0[i] != 0) {
|
||||
LOG_INFO("\tx[%d] = %zx\n", i, l0[i]);
|
||||
size_t* l1 = (size_t*) l0[i];
|
||||
for(int j=0; j<512; j++) {
|
||||
if (l1[j] != 0) {
|
||||
LOG_INFO("\t\ty[%d] = %zx\n", j, l1[j]);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/** @brief Get the base address of the child table
|
||||
*
|
||||
* @param entry The parent entry
|
||||
* @return The child entry
|
||||
*/
|
||||
static inline page_entry_t* get_child_entry(page_entry_t *entry)
|
||||
{
|
||||
size_t child = (size_t) entry;
|
||||
|
||||
child <<= PAGE_MAP_BITS;
|
||||
child &= 0x0000FFFFFFFFFFFFULL;
|
||||
|
||||
return (page_entry_t*) child;
|
||||
}
|
||||
|
||||
/** @brief Get the base address of the parent entry
|
||||
*
|
||||
* @param entry The child entry
|
||||
* @return The parent entry
|
||||
*/
|
||||
static inline page_entry_t* get_parent_entry(page_entry_t *entry)
|
||||
{
|
||||
ssize_t parent = (size_t) entry;
|
||||
|
||||
parent >>= PAGE_MAP_BITS;
|
||||
parent |= 0x0000FF8000000000ULL; //PAGE_MAP_PGT;
|
||||
parent &= ~(sizeof(size_t) - 1); // align to page_entry_t
|
||||
|
||||
return (page_entry_t*) parent;
|
||||
}
|
||||
|
||||
void page_dump(void)
|
||||
{
|
||||
size_t flags = 0;
|
||||
size_t start = 0;
|
||||
size_t end;
|
||||
|
||||
void print(size_t start, size_t end, size_t flags) {
|
||||
size_t size = end - start;
|
||||
|
||||
kprintf("%#018lx-%#018lx %#14x 0x%zx\n", start, end, size, flags & ~PAGE_MASK);
|
||||
}
|
||||
|
||||
void traverse(int level, page_entry_t* entry) {
|
||||
page_entry_t* stop = entry + PAGE_MAP_ENTRIES;
|
||||
for (; entry != stop; entry++) {
|
||||
if (*entry) {
|
||||
if (level) { // do "pre-order" traversal
|
||||
// TODO: handle "inheritance" of page table flags (see get_page_flags())
|
||||
traverse(level-1, get_child_entry(entry));
|
||||
} else {
|
||||
if (!flags) {
|
||||
flags = *entry; //& ~PAGE_MASK;
|
||||
start = entry_to_virt(entry, level);
|
||||
}
|
||||
else if ((flags & ~PAGE_MASK) != (*entry & ~PAGE_MASK)) {
|
||||
end = entry_to_virt(entry, level);
|
||||
print(start, end, flags);
|
||||
|
||||
flags = *entry; // & ~PAGE_MASK;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags) {
|
||||
end = entry_to_virt(entry, level);
|
||||
print(start, end, flags);
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
kprintf("%-18s-%18s %14s %-6s\n", "start", "end", "size", "flags"); // header
|
||||
|
||||
traverse(PAGE_LEVELS-1, (page_entry_t*) 0x0000FFFFFFFFF000ULL);
|
||||
|
||||
if (flags) // workaround to print last mapping
|
||||
print(start, 0L, flags);
|
||||
}
|
||||
|
||||
int page_init(void)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <asm/multiboot.h>
|
||||
#include <asm/irqflags.h>
|
||||
|
||||
#define TLS_OFFSET 8
|
||||
#define TLS_ALIGNBITS 5
|
||||
#define TLS_ALIGNSIZE (1L << TLS_ALIGNBITS)
|
||||
#define TSL_ALIGNMASK ((~0L) << TLS_ALIGNBITS)
|
||||
|
@ -87,6 +88,18 @@ static int init_tls(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void destroy_tls(void)
|
||||
{
|
||||
task_t* curr_task = per_core(current_task);
|
||||
|
||||
// do we need to release the TLS?
|
||||
void* tls_addr = (void*)get_tls();
|
||||
if (tls_addr) {
|
||||
//LOG_INFO("Release TLS at %p\n", (char*)tls_addr - curr_task->tls_size);
|
||||
kfree((char*)tls_addr - curr_task->tls_size - TLS_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
static int thread_entry(void* arg, size_t ep)
|
||||
{
|
||||
|
||||
|
|
|
@ -103,9 +103,9 @@ int page_set_flags(size_t viraddr, uint32_t npages, int flags)
|
|||
int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits, uint8_t do_ipi)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
size_t vpn = viraddr >> PAGE_BITS;
|
||||
size_t first[PAGE_LEVELS];
|
||||
size_t last[PAGE_LEVELS];
|
||||
ssize_t vpn = viraddr >> PAGE_BITS;
|
||||
ssize_t first[PAGE_LEVELS];
|
||||
ssize_t last[PAGE_LEVELS];
|
||||
int8_t send_ipi = 0;
|
||||
|
||||
//kprintf("Map %d pages at 0x%zx\n", npages, viraddr);
|
||||
|
@ -201,8 +201,8 @@ void page_fault_handler(struct state *s)
|
|||
int check_pagetables(size_t vaddr)
|
||||
{
|
||||
int lvl;
|
||||
long vpn = vaddr >> PAGE_BITS;
|
||||
long index[PAGE_LEVELS];
|
||||
ssize_t vpn = vaddr >> PAGE_BITS;
|
||||
ssize_t index[PAGE_LEVELS];
|
||||
|
||||
/* Calculate index boundaries for page map traversal */
|
||||
for (lvl=0; lvl<PAGE_LEVELS; lvl++)
|
||||
|
|
|
@ -230,6 +230,8 @@ void NORETURN do_abort(void);
|
|||
/** @brief This function shall be called by leaving kernel-level tasks */
|
||||
void NORETURN leave_kernel_task(void);
|
||||
|
||||
/** @brief Release the thread local storage of the current thread */
|
||||
void destroy_tls(void);
|
||||
|
||||
/** @brief if a task exists with higher priority, HermitCore switch to it. */
|
||||
void check_scheduling(void);
|
||||
|
|
|
@ -86,7 +86,7 @@ static const int sobufsize = 131072;
|
|||
* maintaining a value, rather their address is their value.
|
||||
*/
|
||||
extern const void kernel_start;
|
||||
extern const void hbss_start;
|
||||
extern const void tdata_end;
|
||||
extern const void tls_start;
|
||||
extern const void tls_end;
|
||||
extern const void __bss_start;
|
||||
|
@ -117,7 +117,7 @@ static int hermit_init(void)
|
|||
size_t sz = (size_t) &percore_end0 - (size_t) &percore_start;
|
||||
|
||||
// initialize .kbss sections
|
||||
memset((void*)&hbss_start, 0x00, (size_t) &__bss_start - (size_t) &hbss_start);
|
||||
memset((void*)&tdata_end, 0x00, (size_t) &__bss_start - (size_t) &tdata_end);
|
||||
|
||||
// initialize .percore section => copy first section to all other sections
|
||||
for(i=1; i<MAX_CORES; i++)
|
||||
|
@ -652,8 +652,8 @@ int hermit_main(void)
|
|||
LOG_INFO("This is Hermit %s, build on %s\n", PACKAGE_VERSION, __DATE__);
|
||||
//LOG_INFO("Isle %d of %d possible isles\n", isle, possible_isles);
|
||||
LOG_INFO("Kernel starts at %p and ends at %p\n", &kernel_start, (size_t)&kernel_start + image_size);
|
||||
//LOG_INFO("TLS image starts at %p and ends at %p (size 0x%zx)\n", &tls_start, &tls_end, ((size_t) &tls_end) - ((size_t) &tls_start));
|
||||
LOG_INFO("BBS starts at %p and ends at %p\n", &hbss_start, (size_t)&kernel_start + image_size);
|
||||
LOG_INFO("TLS image starts at %p and ends at %p (size 0x%zx)\n", &tls_start, &tls_end, ((size_t) &tls_end) - ((size_t) &tls_start));
|
||||
LOG_INFO("BBS starts at %p and ends at %p\n", &tdata_end, (size_t)&kernel_start + image_size);
|
||||
LOG_INFO("Per core data starts at %p and ends at %p\n", &percore_start, &percore_end);
|
||||
LOG_INFO("Per core size 0x%zx\n", (size_t) &percore_end0 - (size_t) &percore_start);
|
||||
if (get_cpu_frequency() > 0)
|
||||
|
|
|
@ -47,8 +47,6 @@ extern atomic_int32_t cpu_online;
|
|||
|
||||
volatile uint32_t go_down = 0;
|
||||
|
||||
#define TLS_OFFSET 8
|
||||
|
||||
/** @brief Array of task structures (aka PCB)
|
||||
*
|
||||
* A task's id will be its position in this array.
|
||||
|
@ -367,7 +365,6 @@ void finish_task_switch(void)
|
|||
void NORETURN do_exit(int arg)
|
||||
{
|
||||
task_t* curr_task = per_core(current_task);
|
||||
void* tls_addr = NULL;
|
||||
const uint32_t core_id = CORE_ID;
|
||||
|
||||
LOG_INFO("Terminate task: %u, return value %d\n", curr_task->id, arg);
|
||||
|
@ -379,12 +376,8 @@ void NORETURN do_exit(int arg)
|
|||
readyqueues[core_id].nr_tasks--;
|
||||
spinlock_irqsave_unlock(&readyqueues[core_id].lock);
|
||||
|
||||
// do we need to release the TLS?
|
||||
tls_addr = (void*)get_tls();
|
||||
if (tls_addr) {
|
||||
//LOG_INFO("Release TLS at %p\n", (char*)tls_addr - curr_task->tls_size);
|
||||
kfree((char*)tls_addr - curr_task->tls_size - TLS_OFFSET);
|
||||
}
|
||||
// release the thread local storage
|
||||
destroy_tls();
|
||||
|
||||
curr_task->status = TASK_FINISHED;
|
||||
|
||||
|
|
|
@ -9,18 +9,20 @@ void* thread_func(void* arg)
|
|||
{
|
||||
id = *((int*) arg);
|
||||
|
||||
printf("Hello Thread!!! id = %d\n", id);
|
||||
printf("Hello thread!!! id = %d\n", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
pthread_t threads[MAX_THREADS];
|
||||
int i, ret, param[MAX_THREADS];
|
||||
int param[MAX_THREADS];
|
||||
|
||||
for(i=0; i<MAX_THREADS; i++) {
|
||||
printf("Hello form main thread! id = %d\n", id);
|
||||
|
||||
for(int i=0; i<MAX_THREADS; i++) {
|
||||
param[i] = i;
|
||||
ret = pthread_create(threads+i, NULL, thread_func, param+i);
|
||||
int ret = pthread_create(threads+i, NULL, thread_func, param+i);
|
||||
if (ret) {
|
||||
printf("Thread creation failed! error = %d\n", ret);
|
||||
return ret;
|
||||
|
@ -28,7 +30,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
/* wait until all threads have terminated */
|
||||
for(i=0; i<MAX_THREADS; i++)
|
||||
for(int i=0; i<MAX_THREADS; i++)
|
||||
pthread_join(threads[i], NULL);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue