2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/thread/thread.c
5 * PURPOSE: Thread functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 Tls functions are modified from WINE
13 #include <kernel32/thread.h>
14 #include <ddk/ntddk.h>
16 #include <internal/i386/segment.h>
21 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
23 LPTHREAD_START_ROUTINE lpStartAddress
,
25 DWORD dwCreationFlags
,
29 return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes
,dwStackSize
,
30 lpStartAddress
,lpParameter
,dwCreationFlags
,lpThreadId
);
40 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
42 LPTHREAD_START_ROUTINE lpStartAddress
,
44 DWORD dwCreationFlags
,
50 OBJECT_ATTRIBUTES ObjectAttributes
;
52 CONTEXT ThreadContext
;
53 INITIAL_TEB InitialTeb
;
54 BOOLEAN CreateSuspended
= FALSE
;
57 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
58 ObjectAttributes
.RootDirectory
= NULL
;
59 ObjectAttributes
.ObjectName
= NULL
;
60 ObjectAttributes
.Attributes
= 0;
61 if ( lpThreadAttributes
!= NULL
) {
62 if ( lpThreadAttributes
->bInheritHandle
)
63 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
64 ObjectAttributes
.SecurityDescriptor
= lpThreadAttributes
->lpSecurityDescriptor
;
66 ObjectAttributes
.SecurityQualityOfService
= NULL
;
68 if ( ( dwCreationFlags
& CREATE_SUSPENDED
) == CREATE_SUSPENDED
)
69 CreateSuspended
= TRUE
;
71 CreateSuspended
= FALSE
;
74 ZwAllocateVirtualMemory(hProcess
,
82 memset(&ThreadContext
,0,sizeof(CONTEXT
));
83 ThreadContext
.Eip
= lpStartAddress
;
84 ThreadContext
.SegGs
= USER_DS
;
85 ThreadContext
.SegFs
= USER_DS
;
86 ThreadContext
.SegEs
= USER_DS
;
87 ThreadContext
.SegDs
= USER_DS
;
88 ThreadContext
.SegCs
= USER_CS
;
89 ThreadContext
.SegSs
= USER_DS
;
90 ThreadContext
.Esp
= BaseAddress
+ dwStackSize
;
91 ThreadContext
.EFlags
= (1<<1) + (1<<9);
94 errCode
= NtCreateThread(&ThreadHandle
,
102 if ( lpThreadId
!= NULL
)
103 memcpy(lpThreadId
, &ClientId
.UniqueThread
,sizeof(ULONG
));
113 WINBOOL STDCALL
SwitchToThread(VOID
)
116 errCode
= NtYieldExecution();
120 DWORD STDCALL
GetCurrentThreadId()
123 return (DWORD
)(GetTeb()->Cid
).UniqueThread
;
126 VOID STDCALL
ExitThread(UINT uExitCode
)
130 errCode
= NtTerminateThread(
134 if ( !NT_SUCCESS(errCode
) ) {
135 SetLastError(RtlNtStatusToDosError(errCode
));
144 LPFILETIME lpCreationTime
,
145 LPFILETIME lpExitTime
,
146 LPFILETIME lpKernelTime
,
147 LPFILETIME lpUserTime
151 KERNEL_USER_TIMES KernelUserTimes
;
153 errCode
= NtQueryInformationThread(hThread
,ThreadTimes
,&KernelUserTimes
,sizeof(KERNEL_USER_TIMES
),&ReturnLength
);
154 if ( !NT_SUCCESS(errCode
) ) {
155 SetLastError(RtlNtStatusToDosError(errCode
));
158 memcpy(lpCreationTime
, &KernelUserTimes
.CreateTime
, sizeof(FILETIME
));
159 memcpy(lpExitTime
, &KernelUserTimes
.ExitTime
, sizeof(FILETIME
));
160 memcpy(lpKernelTime
, &KernelUserTimes
.KernelTime
, sizeof(FILETIME
));
161 memcpy(lpUserTime
, &KernelUserTimes
.UserTime
, sizeof(FILETIME
));
168 STDCALL
GetThreadContext(
174 errCode
= NtGetContextThread(hThread
,lpContext
);
175 if ( !NT_SUCCESS(errCode
) ) {
176 SetLastError(RtlNtStatusToDosError(errCode
));
186 CONST CONTEXT
*lpContext
191 errCode
= NtSetContextThread(hThread
,(void *)lpContext
);
192 if (!NT_SUCCESS(errCode
) ) {
193 SetLastError(RtlNtStatusToDosError(errCode
));
209 THREAD_BASIC_INFORMATION ThreadBasic
;
211 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
212 if ( !NT_SUCCESS(errCode
) ) {
213 SetLastError(RtlNtStatusToDosError(errCode
));
216 memcpy( lpExitCode
,&ThreadBasic
.ExitStatus
,sizeof(DWORD
));
229 ULONG PreviousResumeCount
;
231 errCode
= NtResumeThread(hThread
,&PreviousResumeCount
);
232 if ( !NT_SUCCESS(errCode
) ) {
233 SetLastError(RtlNtStatusToDosError(errCode
));
236 return PreviousResumeCount
;
246 ULONG PreviousSuspendCount
;
248 errCode
= NtSuspendThread(hThread
,&PreviousSuspendCount
);
249 if ( !NT_SUCCESS(errCode
) ) {
250 SetLastError(RtlNtStatusToDosError(errCode
));
253 return PreviousSuspendCount
;
259 SetThreadAffinityMask(
261 DWORD dwThreadAffinityMask
276 THREAD_BASIC_INFORMATION ThreadBasic
;
278 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
279 if ( !NT_SUCCESS(errCode
) ) {
280 SetLastError(RtlNtStatusToDosError(errCode
));
283 ThreadBasic
.BasePriority
= nPriority
;
284 errCode
= NtSetInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
));
285 if ( !NT_SUCCESS(errCode
) ) {
286 SetLastError(RtlNtStatusToDosError(errCode
));
300 THREAD_BASIC_INFORMATION ThreadBasic
;
302 errCode
= NtQueryInformationThread(hThread
,ThreadBasicInformation
,&ThreadBasic
,sizeof(THREAD_BASIC_INFORMATION
),&DataWritten
);
303 if ( !NT_SUCCESS(errCode
) ) {
304 SetLastError(RtlNtStatusToDosError(errCode
));
305 return THREAD_PRIORITY_ERROR_RETURN
;
307 return ThreadBasic
.BasePriority
;
311 /* (WIN32) Thread Local Storage ******************************************** */
316 DWORD dwTlsIndex
= GetTeb()->dwTlsIndex
;
319 void **TlsData
= GetTeb()->TlsData
;
322 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
324 TlsData
[dwTlsIndex
] = NULL
;
325 return (dwTlsIndex
++);
327 return (0xFFFFFFFFUL
);
331 TlsFree(DWORD dwTlsIndex
)
338 TlsGetValue(DWORD dwTlsIndex
)
342 void **TlsData
= GetTeb()->TlsData
;
345 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
348 SetLastError(NO_ERROR
);
349 return (TlsData
[dwTlsIndex
]);
356 TlsSetValue(DWORD dwTlsIndex
, LPVOID lpTlsValue
)
360 void **TlsData
= GetTeb()->TlsData
;
363 if (dwTlsIndex
< sizeof(TlsData
) / sizeof(TlsData
[0]))
366 TlsData
[dwTlsIndex
] = lpTlsValue
;
372 /*************************************************************/