Здравствуйте, okman, Вы писали:
O>Здравствуйте, AlexGin, Вы писали:
AG>>while(lck.test_and_set(std::memory_order_acquire)) [b]// здесь, возможно, придется подождать!
O>Спинлок в такой имплементации — это вообще, как по мне, плохая идея.
Вот, я тоже об этом подумал. Т.к если есть сначала дешевый test в цикле, то шину и кеш не грузим,
а затем по факту освообждения переходим к шагу два с попыткой атомарно захватить. Если не успели — возвращаемся на дешевый цикл чтения.
O>Во-первых, постоянно теребить глобальную переменную с xchg/cmpxchg и блокировкой шины — не есть гуд O>(bus traffic и все такое). Как минимум, тут надо применять стратегию не "test and set", а O>"test test and set" + какую-то разгрузку в виде yield/pause/Sleep/etc.
А такое можно реализовать легковесно в user mode не отдавая контекст ядру/планировщику?
O>Во-вторых, на однопроцессорной машине крутиться в спин-цикле бессмысленно, так как лок никто в O>это время не освободит.
O>Ну и в-третьих, если между захватом и освобождением лока поток будет вытеснен, получится O>очень некрасивая ситуация по отношению к другим потокам, которые ждут его освобождения. O>Особенно если лок не гарантирует порядок захвата. Так легко и систему завесить, особенно если O>такой спинлок применять где-нибудь в критических местах — драйверы, всякие системные O>обработчики и т.д. Встречал на практике.
Любопытный вопрос. А какие практики используются вместо этого в ядре?