Получение блокировки гораздо больше, чем простая инструкция процессора.Стоимость попытки приобрести его и не получить его очень высока.Документально, чтобы быть где-то между 2000 и 10000 машинных инструкций.Более высокое число для контекста потока переключается на поток в другом процессе, который требует перезагрузки таблиц перевода страниц виртуальной памяти.
Очень распространенная стратегия, которая имеет смысл в многоядерных процессорах, - это спин-ожидание.Код зацикливается, сильно загружая циклы процессора, пытаясь получить блокировку.Точное количество времени, которое он проводит в этом цикле, технически является настраиваемым элементом, но на практике не имеет большого значения.
В любом случае, задачей CLR и компилятора является скрыть детали реализации.,Одним из основных классов, который делает это, является класс Monitor.Он используется, когда вы используете оператор блокировки в C #, например, компилятор автоматически преобразует его в вызов Monitor.Enter, автоматически генерируя блок try и finally, блок finally выполняет метод Leave ().
Реализация этих методов в CLR.Там есть довольно хороший кусок кода, другая вещь, которую он делает, имеет дело с "честностью".Который гарантирует, что потоки не могут голодать, пытаясь получить блокировку.Этот код написан на C ++, все еще довольно далеко от необработанных инструкций процессора.В конечном итоге это сводится к реальному коду, который реализует фактическую блокировку.Да, это написано на ассемблере, по крайней мере, в общедоступной версии CLR.Этот код находится в PAL (уровне адаптера платформы), его версия для x86 выглядит следующим образом:
FASTCALL_FUNC CompareExchangeMP,12
_ASSERT_ALIGNED_4_X86 ecx
mov eax, [esp+4] ; Comparand
lock cmpxchg [ecx], edx
retn 4 ; result in EAX
FASTCALL_ENDFUNC CompareExchangeMP
Инструкция CPU cmpxchng с префиксом блокировки является типичной для реализации блокировок.Ваш xadd тоже покрыт, используется для Interlocked.Add:
FASTCALL_FUNC ExchangeAddUP,8
_ASSERT_ALIGNED_4_X86 ecx
xadd [ecx], edx ; Add Value to Target
mov eax, edx
retn
FASTCALL_ENDFUNC ExchangeAddUP
Но это обычно не используется для блокировок.Если вы хотите убедиться в этом сами, скачайте исходный код SSCLI20 и посмотрите clr \ src \ wm \ i386 \ asmhelpers.asm.Используется ли это на самом деле в текущей версии CLR - вопрос открытый.Это довольно ядро, так что скорее всего.Реализации метода Monitor находятся в clr \ vm \ syncblk.cpp, класс AwareLock.Я почти уверен, что его версия SSCLI20 - это не то, что работает на вашей машине, они возятся с алгоритмом "справедливости".