Параллельный доступ к неперекрывающимся диапазонам RTL_BITMAP - PullRequest
0 голосов
/ 21 июня 2019

В моем драйвере устройства есть растровое изображение, реализованное с использованием объекта Windows RTL_BITMAP и обработанное с помощью подпрограмм растрового изображения RtlXxx ( RtlSetBits , RtlCheckBit и т. Д.) , который используется несколькими потоками.

Каждый поток ограничен чтением / записью только определенного диапазона битов в битовой карте. Диапазон, к которому обращается каждый поток, не перекрывается с диапазоном, к которому обращается каждый другой поток, т. Е. Ни один из потоков не интересуется каким-либо одним и тем же битом.

например.,

001110100101011110011101010101010100001111...10010101101001
<--thread A--><--thread B--><--thread C-->...<--thread Z-->

Нет никаких гарантий относительно количества битов в диапазоне каждого потока, и, следовательно, нет никаких гарантий относительно выравнивания памяти. Например, потоку A могут быть назначены биты [0, 13], а потоку B назначены биты [14, 27]. Это означает, что, как правило, биты, используемые одним потоком, могут храниться в памяти в том же байте, что и биты, используемые другим потоком.

Безопасно ли манипулировать растровым изображением из нескольких потоков одновременно, например, без синхронизации, если биты, к которым обращается каждый поток, уникальны для этого потока?

Меня беспокоит то, что операции с битами, которые разделяют одно и то же слово в памяти, могут привести к противоречивым результатам. Например, операция «установить бит» может быть реализована примерно так:

  1. загрузить регистр со словом, содержащим бит из памяти
  2. OR соответствующий бит в регистре
  3. сохранить регистр обратно в память

Если бы это была не атомарная операция, то, если два потока пытаются установить два разных бита, которые случайно сохраняются в одном и том же общем слове, один из битов может быть "потерян".

Разборка подпрограммы RtlSetBit в ntoskrnl, похоже, что наборы битов выполняются с использованием bts:

fffff802`ac6620dc 488b4108        mov     rax,qword ptr [rcx+8]
fffff802`ac6620e0 0fab10          bts     dword ptr [rax],edx
fffff802`ac6620e3 c3              ret

Это может показаться достаточно атомарным, но в целом этого недостаточно.

...