diff options
author | midipix <writeonce@midipix.org> | 2015-03-08 13:23:20 -0400 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2015-03-08 13:23:20 -0400 |
commit | 86062740f1e8eeb4c554055cf304dc1e0e87ea43 (patch) | |
tree | 35d8309221f4fd2050fefbc1b3b3957a1099ce8a /arch/nt64/pthread_arch.h | |
parent | 41058bd82ed2ae880c463d61e5702aef07681bf0 (diff) | |
download | mmglue-86062740f1e8eeb4c554055cf304dc1e0e87ea43.tar.bz2 mmglue-86062740f1e8eeb4c554055cf304dc1e0e87ea43.tar.xz |
initial commit of core port files.
signed-off by Z. Gilboa; see copying.midipix (9cd0746c) for additional information.
Diffstat (limited to 'arch/nt64/pthread_arch.h')
-rw-r--r-- | arch/nt64/pthread_arch.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/nt64/pthread_arch.h b/arch/nt64/pthread_arch.h new file mode 100644 index 0000000..98babcd --- /dev/null +++ b/arch/nt64/pthread_arch.h @@ -0,0 +1,74 @@ +#include <stddef.h> + +#define TP_ADJ(p) (p) +#define CANCEL_REG_IP 16 + +extern uintptr_t __teb_sys_idx; +extern uintptr_t __teb_libc_idx; + +struct __os_tib { + void * exception_list; + void * stack_base; + void * stack_limit; +}; + +static __inline__ void * __os_get_teb_address(void) +{ + void * ptrRet; + __asm__ __volatile__ ( + "mov %%gs:0x30, %0\n\t" + : "=r" (ptrRet) : : + ); + return ptrRet; +} + + +static inline void __pthread_convert(void) +{ + /* (third-party thread support) */ + __asm__ __volatile__ ( + "push %rax\n\t" + "movq __psx_vtbl,%rax\n\t" + "call *(%rax)\n\t" + "pop %rax\n\t" + ); +} + + +static inline struct pthread ** __psx_tlca(void) +{ + struct pthread ** ptlca; + struct __os_tib * tib; + void ** slots; + void *** xslots; + uintptr_t sys_idx; + + tib = __os_get_teb_address(); + sys_idx = __teb_sys_idx; + + if (sys_idx < 64) { + slots = (void **)((uintptr_t)tib + 0x1480); + ptlca = (struct pthread **)(slots[sys_idx]); + } else { + xslots = (void ***)((uintptr_t)tib + 0x1780); + slots = *xslots; + ptlca = (struct pthread **)(slots[sys_idx - 64]); + } + + return ptlca; +} + + +static inline struct pthread * __pthread_self(void) +{ + struct pthread ** ptlca; + + ptlca = __psx_tlca(); + if (ptlca) return *ptlca; + + /* (third-party thread) */ + __pthread_convert(); + ptlca = __psx_tlca(); + return *ptlca; +} + |