我的设备驱动程序中有一个位图,该位图是使用Windows RTL_BITMAP对象实现的,并使用RtlXxx位图例程(RtlSetBits,RtlCheckBit等)进行操作,该位图在多个线程。
每个线程只能读取/写入位图中的特定范围的位。每个线程访问的范围与其他线程访问的范围不重叠,即,没有两个线程对任何相同的位感兴趣。
例如
001110100101011110011101010101010100001111...10010101101001
<--thread A--><--thread B--><--thread C-->...<--thread Z-->
不能保证每个线程范围内的位数,因此不能保证内存对齐。例如,可能为线程A分配了位[0、13],给线程B分配了位[14、27]。这意味着,通常,一个线程使用的位可以与另一线程使用的位在同一字节中保存在内存中。
只要每个线程访问的位对于该线程都是唯一的,是否可以安全地同时(例如,不同步)操作多个线程中的位图?
我担心的是,涉及在内存中共享同一字的位的操作可能会产生不一致的结果。例如,“设置位”操作可以通过以下方式实现:
OR
进入寄存器的适当位如果这不是原子操作,那么如果两个线程试图设置碰巧存储在同一共享字中的两个不同位,则这些位之一可能会“丢失”。
在ntoskrnl中反汇编RtlSetBit例程,似乎使用bts
执行位设置:
fffff802`ac6620dc 488b4108 mov rax,qword ptr [rcx+8]
fffff802`ac6620e0 0fab10 bts dword ptr [rax],edx
fffff802`ac6620e3 c3 ret
这似乎足够原子,但总体上似乎还不够依靠。