使用用户模式和内核之间共享内存的慢速通信

Slow communication using shared memory between user mode and kernel

本文关键字:内存 通信 共享 之间 用户 模式 内核      更新时间:2023-10-16

我正在Windows内核中运行一个线程,该线程通过共享存储器与应用程序通信。一切正常,除了由于睡眠循环而沟通缓慢。我一直在调查旋转锁,静音和互锁的旋转锁,但无法真正弄清楚。我还考虑了Windows事件,但不知道该事件的性能。请建议什么是一个更快的解决方案,以使沟通能否超越共享记忆可能暗示Windows事件。

内核代码

typedef struct _SHARED_MEMORY
{
    BOOLEAN mutex;
    CHAR data[BUFFER_SIZE];
} SHARED_MEMORY, *PSHARED_MEMORY;
ZwCreateSection(...)
ZwMapViewOfSection(...)
while (TRUE) {
    if (((PSHARED_MEMORY)SharedSection)->mutex == TRUE) {
      //... do work...
      ((PSHARED_MEMORY)SharedSection)->mutex = FALSE;
    }
    KeDelayExecutionThread(KernelMode, FALSE, &PollingInterval);
}

应用程序代码

OpenFileMapping(...)
MapViewOfFile(...)
...
RtlCopyMemory(&SM->data, WriteData, Size);
SM->mutex = TRUE;
while (SM->mutex != FALSE) {
    Sleep(1); // Slow and removing it will cause an infinite loop
}
RtlCopyMemory(ReadData, &SM->data, Size);

更新1 目前,这是我提出的最快解决方案:

while(InterlockedCompareExchange(&SM->mutex, FALSE, FALSE));

但是,我发现您需要进行交流很有趣,并且没有比较的功能。

您不想使用InterlockedCompareexchange。它燃烧CPU,使另一个线程共享该物理核心可能需要的核心资源饱和,并且可以饱和。

您确实需要做两件事:

1)编写InterlockedGet功能并使用它。

2)防止循环燃烧CPU资源,并在最终被封锁时将所有错误预测分支的母亲带走。

对于1,众所周知,这在所有支持InterlockedCompareExchange的编译器上都可以使用,至少上次我检查:

__inline static int InterlockedGet(int *val)
{
    return *((volatile int *)val);
}

为2,将其作为等待循环的主体:

__asm
{
    rep nop
}

对于x86 cpu,这是为解决资源饱和度和分支预测问题的指定。

将其放在一起:

while ((*(volatile int *) &SM->mutex) != FALSE) {
    __asm
    {
        rep nop
    }
}

如果不合适,请根据需要更改int