Здравствуйте, Alexander G, Вы писали:
AG>Как-то можно используя документируемые API его убрать?
Давно уже не трогал WinAPI, но что такое SpinCount? Тип у него ULONG_PTR, что больше похоже на указатель, чем на значение. Учитывая, что критические секции нельзя копировать и перемещать, кажется, что так и есть.
Re[2]: Критическая секция, как совсем отключить spin count
Здравствуйте, Nuzhny, Вы писали:
N>Давно уже не трогал WinAPI, но что такое SpinCount?
Если ресурс занят, то перед тем, как ждать в ядре, может быть предпринято некоторое количество попыток проверить, не освободился ли ресурс.
На многопроцессорных/многоядерных системах и для занимаемых на непродолжительное время ресурсов это может улучшить перформанс.
Для продолжительно занимаемых ресурсов от такого больше вреда, чем пользы.
На однопроцессорных/одноядерных системах это бесполезно, и оно не включается.
В книге Рихтера тема раскрыта и в одкументации той же InitializeCriticalSectionAndSpinCount.
N>Тип у него ULONG_PTR, что больше похоже на указатель, чем на значение.
Оно там для выравнивания с /Zp1, даже комментарий есть:
typedef struct _RTL_CRITICAL_SECTION {
...
ULONG_PTR SpinCount; // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
Здравствуйте, Mr.Delphist, Вы писали:
MD>Здравствуйте, Alexander G, Вы писали:
AG>>Пробую разные варианты задания нулевого спин каунта для крит. секции
MD>А что возвращается в качестве результата? Если вызовы по факту неуспешны, то что говорит GetLastError?
Все вызовы успешны, значение GetLastError не меняется.
В принципе эти функции никогда не фейлят, обычная InitializeCriticalSection даже не возвращает значение
(В старых версиях Windows она могла бросать SEH-исключения, сейчас она просто всегда успешна).
Функция SetCriticalSectionSpinCount в примере возвращает 0x7D0, что также подтверждает, что дефолтный спин каунт 0x7D0, а 0x02000000 — это флаг.
Русский военный корабль идёт ко дну!
Re[3]: Критическая секция, как совсем отключить spin count
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, Mr.Delphist, Вы писали:
MD>>Здравствуйте, Alexander G, Вы писали:
AG>>>Пробую разные варианты задания нулевого спин каунта для крит. секции
MD>>А что возвращается в качестве результата? Если вызовы по факту неуспешны, то что говорит GetLastError?
AG>Все вызовы успешны, значение GetLastError не меняется.
AG>В принципе эти функции никогда не фейлят, обычная InitializeCriticalSection даже не возвращает значение AG>(В старых версиях Windows она могла бросать SEH-исключения, сейчас она просто всегда успешна).
AG>Функция SetCriticalSectionSpinCount в примере возвращает 0x7D0, что также подтверждает, что дефолтный спин каунт 0x7D0, а 0x02000000 — это флаг.
Кстати, я тут нагуглил разбор потрохов этого API — возможно, будет интересно:
Нужно передать ненулевой спин каунт в InitializeCriticalSectionAndSpinCount или InitializeCriticalSectionEx, тогда дополнительных флагов не будет:
::InitializeCriticalSectionEx(&cs, 1, 0);
printf("Spin count after explicit one %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);
Это выведет 1, спин каунт 1 — это почти что ноль. Последующим вызовом SetCriticalSectionSpinCount можно и строго ноль получить:
::InitializeCriticalSectionEx(&cs, 1, 0);
::SetCriticalSectionSpinCount(&cs, 0);
printf("Spin count after explicit one and then reset to zero %08X\n", cs.SpinCount);
::DeleteCriticalSection(&cs);