Skip to content

Commit 0e207a0

Browse files
committed
Kernel / Library - Introduce thread & Memory poll to process and pull events
This is highly based on #307 without the async logic. The reason is to avoid using the kernel NotificationLoop that was dispatching requests to workers (userland thread) sequentially. It has a high cost to do a thread switch each time to wake up the workers. The current logic is nice when you want workers to be async but as we have threads (and now a thread poll) dedicated to pull and process events, we can make them synchronously wait for new events and take them from the request list themself. This commit introduces the logic of a single main thread that polls events by batch and dispatches them to other threads and keeps the last one for itself to process and send the response to the kernel. Each thread waken will do the same and pull new events at the same time. If none is returned, the thread goes back to sleep and otherwise does the same as the main thread (dispatch and process). The difference is that the main thread waits indefinitely for new events while others wait 100ms in the kernel before returning back to userland.This and the memory poll also added, offer a great flexibility of resources especially on heavy load. This CL is huge but the perf that comes with it are about 10-35% on sequential requests but in the real world with the thread poll the perf are way above. @Corillian full rewrite of FindFiles improved the perf between 100-250%...
1 parent c167bfc commit 0e207a0

40 files changed

+2803
-1769
lines changed

dokan/cleanup.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,25 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
2222

2323
#include "dokani.h"
2424

25-
VOID DispatchCleanup(HANDLE Handle, PEVENT_CONTEXT EventContext,
26-
PDOKAN_INSTANCE DokanInstance) {
27-
PEVENT_INFORMATION eventInfo;
28-
DOKAN_FILE_INFO fileInfo;
29-
PDOKAN_OPEN_INFO openInfo;
30-
ULONG sizeOfEventInfo = DispatchGetEventInformationLength(0);
25+
VOID DispatchCleanup(PDOKAN_IO_EVENT IoEvent) {
26+
CheckFileName(IoEvent->EventContext->Operation.Cleanup.FileName);
3127

32-
CheckFileName(EventContext->Operation.Cleanup.FileName);
28+
CreateDispatchCommon(IoEvent, 0);
3329

34-
eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance,
35-
&fileInfo, &openInfo);
30+
IoEvent->EventResult->Status = STATUS_SUCCESS; // return success at any case
3631

37-
eventInfo->Status = STATUS_SUCCESS; // return success at any case
32+
DbgPrint("###Cleanup file handle = 0x%p, eventID = %04d, event Info = 0x%p\n",
33+
IoEvent->DokanOpenInfo,
34+
IoEvent->DokanOpenInfo != NULL ? IoEvent->DokanOpenInfo->EventId
35+
: -1,
36+
IoEvent);
3837

39-
DbgPrint("###Cleanup %04d\n", openInfo != NULL ? openInfo->EventId : -1);
40-
41-
if (DokanInstance->DokanOperations->Cleanup) {
38+
if (IoEvent->DokanInstance->DokanOperations->Cleanup) {
4239
// ignore return value
43-
DokanInstance->DokanOperations->Cleanup(
44-
EventContext->Operation.Cleanup.FileName, &fileInfo);
40+
IoEvent->DokanInstance->DokanOperations->Cleanup(
41+
IoEvent->EventContext->Operation.Cleanup.FileName,
42+
&IoEvent->DokanFileInfo);
4543
}
4644

47-
if (openInfo != NULL)
48-
openInfo->UserContext = fileInfo.Context;
49-
50-
SendEventInformation(Handle, eventInfo, sizeOfEventInfo);
51-
ReleaseDokanOpenInfo(eventInfo, &fileInfo, DokanInstance);
52-
free(eventInfo);
45+
EventCompletion(IoEvent);
5346
}

dokan/close.c

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,27 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
2121
*/
2222

2323
#include "dokani.h"
24+
#include "dokan_pool.h"
2425

25-
VOID DispatchClose(HANDLE Handle, PEVENT_CONTEXT EventContext,
26-
PDOKAN_INSTANCE DokanInstance) {
27-
PEVENT_INFORMATION eventInfo;
28-
DOKAN_FILE_INFO fileInfo;
29-
PDOKAN_OPEN_INFO openInfo;
30-
ULONG sizeOfEventInfo = DispatchGetEventInformationLength(0);
26+
VOID DispatchClose(PDOKAN_IO_EVENT IoEvent) {
27+
CheckFileName(IoEvent->EventContext->Operation.Close.FileName);
3128

32-
UNREFERENCED_PARAMETER(Handle);
29+
DbgPrint("###Close file handle = 0x%p, eventID = %04d, event Info = 0x%p\n",
30+
IoEvent->DokanOpenInfo,
31+
IoEvent->DokanOpenInfo != NULL ? IoEvent->DokanOpenInfo->EventId
32+
: -1,
33+
IoEvent);
3334

34-
CheckFileName(EventContext->Operation.Close.FileName);
35-
36-
eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance,
37-
&fileInfo, &openInfo);
38-
39-
eventInfo->Status = STATUS_SUCCESS; // return success at any case
40-
41-
DbgPrint("###Close %04d\n", openInfo != NULL ? openInfo->EventId : -1);
42-
4335
// Driver has simply notifying us of the Close request which he has
4436
// already completed at this stage. Driver is not expecting us
4537
// to reply from this so there is no need to send an EVENT_INFORMATION.
4638

47-
if (openInfo != NULL) {
48-
EnterCriticalSection(&DokanInstance->CriticalSection);
49-
openInfo->FileName = _wcsdup(EventContext->Operation.Close.FileName);
50-
openInfo->OpenCount--;
51-
LeaveCriticalSection(&DokanInstance->CriticalSection);
39+
if (IoEvent->DokanOpenInfo) {
40+
EnterCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
41+
IoEvent->DokanOpenInfo->FileName =
42+
_wcsdup(IoEvent->EventContext->Operation.Close.FileName);
43+
IoEvent->DokanOpenInfo->OpenCount--;
44+
LeaveCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
45+
ReleaseDokanOpenInfo(IoEvent);
5246
}
53-
ReleaseDokanOpenInfo(eventInfo, &fileInfo, DokanInstance);
54-
free(eventInfo);
5547
}

0 commit comments

Comments
 (0)