я не совсем об этом. строго говоря что есть "полноценная" interlocked функция? - это ОДНА машинная команда, выполнение которой, самим процессором выполняется "атомарно" независимо от уровня привелегий, IQRL и аппаратных/программных прерываний.
такие операции могут быть реализованы аппаратно на основе следующих машинных команд x86 архитектуры (к примеру)
InterlockedCompareExchangeCMPXCHG - команда может быть 8/16/32 битной.
или
CMPXCHG8B - делает "Compare EDX:EAX with m64. If equal, set ZF and load ECX:EBX into m64. Else, clear ZF and load m64 into EDX:EAX."
причем обе команды выполняются с обязательным префиксом LOCK!!!! данных префикс обязывает процессор выдать сигнал LOCK грубо говоря на одну из ножек процессора, чтобы заблокировать выполнение операций модификации памяти на других процессорах, модификаций кэша(или еще где либо). .... очень грубо говоря (точнее не разбирался))!
причем приведенные выше инструкции:
"This instruction
is not supported on Intel processors earlier than the Intel486 processors." и "This instruction
is not supported on Intel processors earlier than the Pentium processors" соответственно!
реализация моей любимой
InterlockedExchangeAdd, основана на команде
XADD с префиксом LOCK.
для нее, как мы видим, существует только 32 битная реализация. но зато она есть и в ring-0 и в ring-3, чем очень удобно пользоваться.
а вот очень похожая команда ядра
ExInterlockedAddLargeInteger (для 64 битных аргументов) в kernel уже реализована через дополнительный SpinLock (что в пользовательском режиме - просто невозможно... ну или довольно проблематично) и оно понятно - нет соответствующей команды процессора!
Упомянутая вами
InterlockedAnd64 существует только для архитектур
IPF и x64 по той же причине. и аналога в kernel - для нее нет...
что до ее реализации в Winbase.h... честно говоря наверно ребятам виднее. возможно они играют на тонкостях оптимизации и особенностях переключения нитей. честно скажу - не знаю) поэтому не использую, во избежание) да и надобности не было.
вот такая катавасия)
кстати я тут может быть, немного ошибок в описании наделал. но в качестве иллюстрации - все выглядит как-то так)
PPS строго говоря я с этим довольно давно разбирался... но кажется реализация именно такая) если у кого стоит отладчик ядра - поставьте бряки на указанные функции (в SoftIce это было можно, посмотрите глазами?)
PPS еще один момент. для interlocked функций ядра надо внимательно смотреть на строчку типа
"Interlocked operations cannot be used on non-cached memory." (для InterlockedAnd) - что означает то, что в случае свопируемой памяти, будет сгенерировано исключение с последующей подгрузкой недостающих страниц в оперативную память. что нарушит атомарность выполнения функции.
или "InterlockedCompareExchange is designed for speed and, typically, is implemented inline by a compiler. InterlockedCompareExchange
is atomic only with respect to other InterlockedXxx calls. It does not use a spin lock and can be safely used on pageable data." - - что означает что оба процесса должны использовать доступ к переменной с использованием префикса lock.
таким образом я для себя выделил два основных момента:
атомарная interlocked функция над одной переменной может быть использована(для синхронизации доступа из приложения и драйвера) только в случае:
1. не свопируемой переменной.
2. только в случае если реализация функции может быть выполнена машинной командой с префиксом LOCK. (без используется дополнительного spinLock-а).
я примерно так и поступаю)