2 * System-dependent scheduler support
4 * Copyright 1998 Alexandre Julliard
9 /* Get pointers to the static errno and h_errno variables used by Xlib. This
10 must be done before including <errno.h> makes the variables invisible. */
12 static int *perrno
= &errno
;
14 static int *ph_errno
= &h_errno
;
19 #ifdef HAVE_SYS_SYSCALL_H
20 # include <sys/syscall.h>
28 /* Xlib critical section (FIXME: does not belong here) */
29 CRITICAL_SECTION X11DRV_CritSection
= { 0, };
31 #ifdef HAVE_CLONE_SYSCALL
36 # define CLONE_VM 0x00000100
37 # define CLONE_FS 0x00000200
38 # define CLONE_FILES 0x00000400
39 # define CLONE_SIGHAND 0x00000800
40 # define CLONE_PID 0x00001000
41 /* If we didn't get the flags, we probably didn't get the prototype either */
42 extern int clone( int (*fn
)(void *arg
), void *stack
, int flags
, void *arg
);
43 # endif /* CLONE_VM */
44 #endif /* HAVE_CLONE_SYSCALL */
49 /***********************************************************************
52 * Get the per-thread errno location.
54 int *__errno_location()
56 THDB
*thdb
= THREAD_Current();
57 if (!thdb
) return perrno
;
58 #ifdef NO_REENTRANT_X11
59 /* Use static libc errno while running in Xlib. */
60 if (X11DRV_CritSection
.OwningThread
== (HANDLE
)thdb
->server_tid
)
63 return &thdb
->thread_errno
;
66 /***********************************************************************
69 * Get the per-thread h_errno location.
71 int *__h_errno_location()
73 THDB
*thdb
= THREAD_Current();
74 if (!thdb
) return ph_errno
;
75 #ifdef NO_REENTRANT_X11
76 /* Use static libc h_errno while running in Xlib. */
77 if (X11DRV_CritSection
.OwningThread
== (HANDLE
)thdb
->server_tid
)
80 return &thdb
->thread_h_errno
;
86 THDB
*thdb
= THREAD_Current();
87 if (!thdb
) return perrno
;
88 #ifdef NO_REENTRANT_X11
89 /* Use static libc errno while running in Xlib. */
90 if (X11DRV_CritSection
.OwningThread
== (HANDLE
)thdb
->server_tid
)
93 return &thdb
->thread_errno
;
97 /***********************************************************************
100 * Startup routine for a new thread.
102 static void SYSDEPS_StartThread( THDB
*thdb
)
104 SET_CUR_THREAD( thdb
);
107 _exit(0); /* should never get here */
109 #endif /* USE_THREADS */
112 /***********************************************************************
113 * SYSDEPS_SpawnThread
115 * Start running a new thread.
116 * Return -1 on error, 0 if OK.
118 int SYSDEPS_SpawnThread( THDB
*thread
)
122 #ifdef HAVE_CLONE_SYSCALL
123 if (clone( (int (*)(void *))SYSDEPS_StartThread
, thread
->teb
.stack_top
,
124 CLONE_VM
| CLONE_FS
| CLONE_FILES
| SIGCHLD
, thread
) < 0)
126 /* FIXME: close the child socket in the parent process */
127 /* close( thread->socket );*/
131 DWORD
*sp
= (DWORD
*)thread
->teb
.stack_top
;
132 *--sp
= (DWORD
)thread
;
134 *--sp
= (DWORD
)SYSDEPS_StartThread
;
136 "pushl %2;\n\t" /* RFPROC|RMEM */
137 "pushl $0;\n\t" /* 0 ? */
138 "movl %1,%%eax;\n\t" /* SYS_rfork */
139 ".byte 0x9a; .long 0; .word 7;\n\t" /* lcall 7:0... FreeBSD syscall */
140 "cmpl $0, %%edx;\n\t"
142 "movl %0,%%esp;\n\t" /* father -> new thread */
144 "1:\n\t" /* child -> caller thread */
146 : "r" (sp
), "g" (SYS_rfork
), "g" (RFPROC
|RFMEM
)
150 #else /* !USE_THREADS */
151 FIXME(thread
, "CreateThread: stub\n" );
152 #endif /* USE_THREADS */
157 /***********************************************************************
160 * Exit a running thread; must not return.
161 * Must not make any reference to the thread structures (THDB etc.) as
162 * they have already been deleted.
164 void SYSDEPS_ExitThread(void)
170 /**********************************************************************
171 * NtCurrentTeb (NTDLL.89)
173 * This will crash and burn if called before threading is initialized
175 TEB
* WINAPI
NtCurrentTeb(void)
180 /* Get the TEB self-pointer */
181 __asm__( ".byte 0x64\n\tmovl (%1),%0"
182 : "=r" (teb
) : "r" (&((TEB
*)0)->self
) );
185 return &pCurrentThread
->teb
;
186 #endif /* __i386__ */