summaryrefslogtreecommitdiffhomepage
path: root/arch/nt64/pthread_arch.h
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-03-08 13:23:20 -0400
committermidipix <writeonce@midipix.org>2015-03-08 13:23:20 -0400
commit86062740f1e8eeb4c554055cf304dc1e0e87ea43 (patch)
tree35d8309221f4fd2050fefbc1b3b3957a1099ce8a /arch/nt64/pthread_arch.h
parent41058bd82ed2ae880c463d61e5702aef07681bf0 (diff)
downloadmmglue-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.h74
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;
+}
+