static int allocate_transition_tls(int id) { /* Libc function to initialize TLS-based locale info for ctype functions. */ extern void __ctype_init(void); /* We want to free and then reallocate the tls rather than simply * reinitializing it because its size may have changed. TODO: not sure if * this is right. 0-ing is one thing, but freeing and reallocating can be * expensive, esp if syscalls are involved. Check out glibc's * allocatestack.c for what might work. */ free_transition_tls(id); void *tcb = allocate_tls(); if (!tcb) { errno = ENOMEM; return -1; } /* Setup some intitial TLS data for the newly allocated transition tls. */ void *temp_tcb = get_tls_desc(); set_tls_desc(tcb); begin_safe_access_tls_vars(); __vcoreid = id; __vcore_context = TRUE; __ctype_init(); end_safe_access_tls_vars(); set_tls_desc(temp_tcb); /* Install the new tls into the vcpd. */ set_vcpd_tls_desc(id, tcb); return 0; }
/* Reinitialize / reset / refresh a TLS to its initial values. This doesn't do * it properly yet, it merely frees and re-allocates the TLS, which is why we're * slightly ghetto and return the pointer you should use for the TCB. */ void *reinit_tls(void *tcb) { /* TODO: keep this in sync with the methods used in * allocate_transition_tls() */ free_tls(tcb); return allocate_tls(); }
void allocate_initial_tls(Obj_Entry *list) { void *tpval; /* * Fix the size of the static TLS block by using the maximum * offset allocated so far and adding a bit for dynamic modules to * use. */ tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA; tpval = allocate_tls(list, NULL, TLS_TCB_SIZE, 16); __asm __volatile("mov r13 = %0" :: "r"(tpval)); }
void allocate_initial_tls(Obj_Entry *objs) { char *tls; /* * Fix the size of the static TLS block by using the maximum * offset allocated so far and adding a bit for dynamic modules to * use. */ tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA; tls = (char *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8); sysarch(MIPS_SET_TLS, tls); }
static int allocate_transition_tls(int id) { /* We want to free and then reallocate the tls rather than simply * reinitializing it because its size may have changed. TODO: not sure if * this is right. 0-ing is one thing, but freeing and reallocating can be * expensive, esp if syscalls are involved. Check out glibc's * allocatestack.c for what might work. */ free_transition_tls(id); void *tcb = allocate_tls(); if (!tcb) { errno = ENOMEM; return -1; } set_vcpd_tls_desc(id, tcb); return 0; }