4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS system libraries
6 * FILE: subsys/psx/lib/psxdll/pthread/create.c
7 * PURPOSE: Thread creation
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
13 #include <ddk/ntddk.h>
15 #include <sys/types.h>
17 #include <psx/debug.h>
18 #include <psx/errno.h>
19 #include <napi/i386/segment.h>
21 /* thread creation code adapted from kernel32's CreateRemoteThread() function */
23 static void __threadentry (void *(*start_routine
)(void*), void *arg
)
25 INFO("hello world! thread successfully created");
27 TODO("initialize thread data");
31 INFO("about to call start routine at %#x with argument %#x", start_routine
, arg
);
33 pthread_exit(start_routine(arg
));
36 int pthread_create(pthread_t
*thread
, const pthread_attr_t
*attr
,
37 void *(*start_routine
)(void*), void *arg
)
40 OBJECT_ATTRIBUTES oaThreadAttrs
;
42 CONTEXT cxThreadContext
;
43 INITIAL_TEB itInitialTeb
;
45 ULONG nOldPageProtection
;
48 /* initialize generic object attributes */
49 oaThreadAttrs
.Length
= sizeof(OBJECT_ATTRIBUTES
);
50 oaThreadAttrs
.RootDirectory
= NULL
;
51 oaThreadAttrs
.ObjectName
= NULL
;
52 oaThreadAttrs
.Attributes
= 0;
53 oaThreadAttrs
.SecurityDescriptor
= NULL
;
54 oaThreadAttrs
.SecurityQualityOfService
= NULL
;
56 /* initialize thread attributes */
57 fSuspended
= FALSE
; /* FIXME? really needed? can we hardcode this to FALSE? */
59 /* stack attributes */
60 FIXME("stack size defaulted to 0x100000 - thread attributes ignored");
62 /* stack reserve size */
63 itInitialTeb
.StackReserve
= 0x100000;
65 /* stack commit size */
66 itInitialTeb
.StackCommit
= itInitialTeb
.StackReserve
- PAGESIZE
;
69 itInitialTeb
.StackCommit
+= PAGESIZE
;
72 itInitialTeb
.StackAllocate
= NULL
;
74 nErrCode
= NtAllocateVirtualMemory
77 &itInitialTeb
.StackAllocate
,
79 &itInitialTeb
.StackReserve
,
84 if(!NT_SUCCESS(nErrCode
))
86 return (__status_to_errno(nErrCode
)); /* FIXME? TODO? pthread specific error codes? */
89 itInitialTeb
.StackBase
= (PVOID
)((ULONG
)itInitialTeb
.StackAllocate
+ itInitialTeb
.StackReserve
);
90 itInitialTeb
.StackLimit
= (PVOID
)((ULONG
)itInitialTeb
.StackBase
- itInitialTeb
.StackCommit
);
93 nErrCode
= NtAllocateVirtualMemory
96 &itInitialTeb
.StackLimit
,
98 &itInitialTeb
.StackCommit
,
103 if(!NT_SUCCESS(nErrCode
))
108 itInitialTeb
.StackAllocate
,
109 &itInitialTeb
.StackReserve
,
113 return (__status_to_errno(nErrCode
));
116 /* protect guard page */
117 nErrCode
= NtProtectVirtualMemory
120 itInitialTeb
.StackLimit
,
122 PAGE_GUARD
| PAGE_READWRITE
,
126 if(!NT_SUCCESS(nErrCode
))
131 itInitialTeb
.StackAllocate
,
132 &itInitialTeb
.StackReserve
,
136 return (__status_to_errno(nErrCode
));
139 /* initialize thread registers */
142 memset(&cxThreadContext
, 0, sizeof(CONTEXT
));
143 cxThreadContext
.Eip
= (LONG
)__threadentry
;
144 cxThreadContext
.SegGs
= USER_DS
;
145 cxThreadContext
.SegFs
= TEB_SELECTOR
;
146 cxThreadContext
.SegEs
= USER_DS
;
147 cxThreadContext
.SegDs
= USER_DS
;
148 cxThreadContext
.SegCs
= USER_CS
;
149 cxThreadContext
.SegSs
= USER_DS
;
150 cxThreadContext
.Esp
= (ULONG
)itInitialTeb
.StackBase
- 12;
151 cxThreadContext
.EFlags
= (1<<1) + (1<<9);
153 /* initialize call stack */
154 *((PULONG
)((ULONG
)itInitialTeb
.StackBase
- 4)) = (ULONG
)arg
; /* thread argument */
155 *((PULONG
)((ULONG
)itInitialTeb
.StackBase
- 8)) = (ULONG
)start_routine
; /* thread start routine */
156 *((PULONG
)((ULONG
)itInitialTeb
.StackBase
- 12)) = 0xDEADBEEF; /* "shouldn't see me" */
158 //#error Unsupported architecture
161 INFO("about to create new thread - start routine at %#x, argument %#x", start_routine
, arg
);
164 nErrCode
= NtCreateThread
176 if(!NT_SUCCESS(nErrCode
))
181 itInitialTeb
.StackAllocate
,
182 &itInitialTeb
.StackReserve
,
186 return (__status_to_errno(nErrCode
));
189 /* FIXME? should we return the thread handle or the thread id? */
191 *thread
= (pthread_t
)&ciId
.UniqueThread
; /* for the moment, we return the id */