/* FUNCTIONS ***************************************************************/
+NTSTATUS
+NTAPI
+RtlpStartThread(IN PTHREAD_START_ROUTINE Function,
+ IN PVOID Parameter,
+ OUT PHANDLE ThreadHandle)
+{
+ /* Create a native worker thread -- used for SMSS, CSRSS, etc... */
+ return RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ 0,
+ Function,
+ Parameter,
+ ThreadHandle,
+ NULL);
+}
+
+NTSTATUS
+NTAPI
+RtlpExitThread(IN NTSTATUS ExitStatus)
+{
+ /* Kill a native worker thread -- used for SMSS, CSRSS, etc... */
+ return NtTerminateThread(NtCurrentThread(), ExitStatus);
+}
+
+PRTL_START_POOL_THREAD RtlpStartThreadFunc = RtlpStartThread;
+PRTL_EXIT_POOL_THREAD RtlpExitThreadFunc = RtlpExitThread;
+
#define MAX_WORKERTHREADS 0x100
#define WORKERTHREAD_CREATION_THRESHOLD 0x5
static LONG ThreadPoolIOWorkerThreadsRequests;
static LONG ThreadPoolIOWorkerThreadsLongRequests;
-#define IsThreadPoolInitialized() ((volatile LONG)ThreadPoolInitialized == 1)
+#define IsThreadPoolInitialized() (*((volatile LONG*)&ThreadPoolInitialized) == 1)
static NTSTATUS
RtlpInitializeThreadPool(VOID)
do
{
- InitStatus = _InterlockedCompareExchange(&ThreadPoolInitialized,
+ InitStatus = InterlockedCompareExchange(&ThreadPoolInitialized,
2,
0);
if (InitStatus == 0)
Finish:
/* Initialization done */
- _InterlockedExchange(&ThreadPoolInitialized,
+ InterlockedExchange(&ThreadPoolInitialized,
1);
break;
}
Timeout.QuadPart = -10000LL; /* Wait for 100ms */
/* Start the thread */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- FALSE,
- 0,
- 0,
- 0,
- StartRoutine,
- (PVOID)&WorkerInitialized,
- &ThreadHandle,
- NULL);
-
+ Status = RtlpStartThreadFunc(StartRoutine, (PVOID)&WorkerInitialized, &ThreadHandle);
if (NT_SUCCESS(Status))
{
+ NtResumeThread(ThreadHandle, NULL);
+
/* Poll until the thread got a chance to initialize */
while (WorkerInitialized == 0)
{
}
/* update the requests counter */
- _InterlockedDecrement(&ThreadPoolWorkerThreadsRequests);
+ InterlockedDecrement(&ThreadPoolWorkerThreadsRequests);
if (WorkItem.Flags & WT_EXECUTELONGFUNCTION)
{
- _InterlockedDecrement(&ThreadPoolWorkerThreadsLongRequests);
+ InterlockedDecrement(&ThreadPoolWorkerThreadsLongRequests);
}
}
{
NTSTATUS Status = STATUS_SUCCESS;
- _InterlockedIncrement(&ThreadPoolWorkerThreadsRequests);
+ InterlockedIncrement(&ThreadPoolWorkerThreadsRequests);
if (WorkItem->Flags & WT_EXECUTELONGFUNCTION)
{
- _InterlockedIncrement(&ThreadPoolWorkerThreadsLongRequests);
+ InterlockedIncrement(&ThreadPoolWorkerThreadsLongRequests);
}
if (WorkItem->Flags & WT_EXECUTEINPERSISTENTTHREAD)
if (!NT_SUCCESS(Status))
{
- _InterlockedDecrement(&ThreadPoolWorkerThreadsRequests);
+ InterlockedDecrement(&ThreadPoolWorkerThreadsRequests);
if (WorkItem->Flags & WT_EXECUTELONGFUNCTION)
{
- _InterlockedDecrement(&ThreadPoolWorkerThreadsLongRequests);
+ InterlockedDecrement(&ThreadPoolWorkerThreadsLongRequests);
}
}
}
/* update the requests counter */
- _InterlockedDecrement(&ThreadPoolIOWorkerThreadsRequests);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreadsRequests);
if (WorkItem.Flags & WT_EXECUTELONGFUNCTION)
{
- _InterlockedDecrement(&ThreadPoolIOWorkerThreadsLongRequests);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreadsLongRequests);
}
}
ASSERT(IoThread != NULL);
- _InterlockedIncrement(&ThreadPoolIOWorkerThreadsRequests);
+ InterlockedIncrement(&ThreadPoolIOWorkerThreadsRequests);
if (WorkItem->Flags & WT_EXECUTELONGFUNCTION)
{
/* We're about to queue a long function, mark the thread */
IoThread->Flags |= WT_EXECUTELONGFUNCTION;
- _InterlockedIncrement(&ThreadPoolIOWorkerThreadsLongRequests);
+ InterlockedIncrement(&ThreadPoolIOWorkerThreadsLongRequests);
}
/* It's time to queue the work item */
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to queue APC for work item 0x%p\n", WorkItem->Function);
- _InterlockedDecrement(&ThreadPoolIOWorkerThreadsRequests);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreadsRequests);
if (WorkItem->Flags & WT_EXECUTELONGFUNCTION)
{
- _InterlockedDecrement(&ThreadPoolIOWorkerThreadsLongRequests);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreadsLongRequests);
}
}
BOOLEAN Terminate;
NTSTATUS Status = STATUS_SUCCESS;
- if (_InterlockedIncrement(&ThreadPoolIOWorkerThreads) > MAX_WORKERTHREADS)
+ if (InterlockedIncrement(&ThreadPoolIOWorkerThreads) > MAX_WORKERTHREADS)
{
/* Oops, too many worker threads... */
goto InitFailed;
DPRINT1("Failed to create handle to own thread! Status: 0x%x\n", Status);
InitFailed:
- _InterlockedDecrement(&ThreadPoolIOWorkerThreads);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreads);
/* Signal initialization completion */
- _InterlockedExchange((PLONG)Parameter,
+ InterlockedExchange((PLONG)Parameter,
1);
- RtlExitUserThread(Status);
+ RtlpExitThreadFunc(Status);
return 0;
}
(PLIST_ENTRY)&ThreadInfo.ListEntry);
/* Signal initialization completion */
- _InterlockedExchange((PLONG)Parameter,
+ InterlockedExchange((PLONG)Parameter,
1);
for (;;)
/* FIXME - figure out an effective method to determine if it's appropriate to
lower the number of threads. For now let's always terminate if there's
at least one thread and no queued items. */
- Terminate = ((volatile LONG)ThreadPoolIOWorkerThreads - (volatile LONG)ThreadPoolIOWorkerThreadsLongRequests >= WORKERTHREAD_CREATION_THRESHOLD) &&
- ((volatile LONG)ThreadPoolIOWorkerThreadsRequests == 0);
+ Terminate = (*((volatile LONG*)&ThreadPoolIOWorkerThreads) - *((volatile LONG*)&ThreadPoolIOWorkerThreadsLongRequests) >= WORKERTHREAD_CREATION_THRESHOLD) &&
+ (*((volatile LONG*)&ThreadPoolIOWorkerThreadsRequests) == 0);
if (Terminate)
{
if (Terminate)
{
/* Rundown the thread and unlink it from the list */
- _InterlockedDecrement(&ThreadPoolIOWorkerThreads);
+ InterlockedDecrement(&ThreadPoolIOWorkerThreads);
RemoveEntryList((PLIST_ENTRY)&ThreadInfo.ListEntry);
}
}
NtClose(ThreadInfo.ThreadHandle);
- RtlExitUserThread(Status);
+ RtlpExitThreadFunc(Status);
return 0;
}
PKNORMAL_ROUTINE ApcRoutine;
NTSTATUS Status = STATUS_SUCCESS;
- if (_InterlockedIncrement(&ThreadPoolWorkerThreads) > MAX_WORKERTHREADS)
+ if (InterlockedIncrement(&ThreadPoolWorkerThreads) > MAX_WORKERTHREADS)
{
/* Signal initialization completion */
- _InterlockedExchange((PLONG)Parameter,
+ InterlockedExchange((PLONG)Parameter,
1);
/* Oops, too many worker threads... */
- RtlExitUserThread(Status);
+ RtlpExitThreadFunc(Status);
return 0;
}
/* Signal initialization completion */
- _InterlockedExchange((PLONG)Parameter,
+ InterlockedExchange((PLONG)Parameter,
1);
for (;;)
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
+ (void)0;
}
_SEH2_END;
}
{
/* FIXME - we might want to optimize this */
if (TimeoutCount++ > 2 &&
- (volatile LONG)ThreadPoolWorkerThreads - (volatile LONG)ThreadPoolWorkerThreadsLongRequests >= WORKERTHREAD_CREATION_THRESHOLD)
+ *((volatile LONG*)&ThreadPoolWorkerThreads) - *((volatile LONG*)&ThreadPoolWorkerThreadsLongRequests) >= WORKERTHREAD_CREATION_THRESHOLD)
{
Terminate = TRUE;
}
if (Terminate)
{
- _InterlockedDecrement(&ThreadPoolWorkerThreads);
+ InterlockedDecrement(&ThreadPoolWorkerThreads);
Status = STATUS_SUCCESS;
break;
}
}
}
- RtlExitUserThread(Status);
+ RtlpExitThreadFunc(Status);
return 0;
}
/* Grow the thread pool */
Status = RtlpStartWorkerThread(RtlpIoWorkerThreadProc);
- if (!NT_SUCCESS(Status) && (volatile LONG)ThreadPoolIOWorkerThreads != 0)
+ if (!NT_SUCCESS(Status) && *((volatile LONG*)&ThreadPoolIOWorkerThreads) != 0)
{
/* We failed to create the thread, but there's at least one there so
we can at least queue the request */
/* Grow the thread pool */
Status = RtlpStartWorkerThread(RtlpWorkerThreadProc);
- if (!NT_SUCCESS(Status) && (volatile LONG)ThreadPoolWorkerThreads != 0)
+ if (!NT_SUCCESS(Status) && *((volatile LONG*)&ThreadPoolWorkerThreads) != 0)
{
/* We failed to create the thread, but there's at least one there so
we can at least queue the request */
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlSetThreadPoolStartFunc(IN PRTL_START_POOL_THREAD StartPoolThread,
+ IN PRTL_EXIT_POOL_THREAD ExitPoolThread)
+{
+ RtlpStartThreadFunc = StartPoolThread;
+ RtlpExitThreadFunc = ExitPoolThread;
+ return STATUS_SUCCESS;
+}