немного хардкора
Sep. 4th, 2011 01:47 pmзабавную штучку я раскопал, а потом и нашел по ссылке аналогичные наблюдения
http://groups.google.com/group/lock-free/browse_thread/thread/d7ac22f807d1d439
Возможно и похоже (я не проверял, у меня сейчас на виндах нет ни дебаггера ни даже С++, а дискуссия по ссылке чуток неадеквата), что сейчас под виндоуз невозможно написать 100% надёжный lock-free код, возвращающий память системе с помощью вызова free и подобного, а не возвращающий выделенную память в пул, либо использующий сборщик мусора.
Причина несколько тонка - в результате освобождения памяти может произойти исключение при доступе по "старому" указателю. Само по себе это не беда - можно надеяться словить исключение и обработать его как факт того, что указатель устарел.
Проблема, однако, в том, что адресуясь по устаревшим указателям наугад можно нечаянно задеть guard-page другого треда, а это, как это не смешно, приводит через непродолжительное время к терминации процесса.
Т.е. я опять ж не проверял, но не исключено, что функция InterlockedPopEntrySList имеет неустранимый, в рамках старого ядра виндов, баг.
Вообще, чего б этому самому ядру не заботиться о том, чтобы не сносить аттрибут guard-pages если они не относятся к стеку текущего треда? Ведь уже так или иначе исключение по доступу к guard page стека делается в kernel-mode, так отчего бы и нет? Впрочем, тогда либо придется вводить дополнительный аттрибут памяти "stack guard page", либо тупо проверять, а не относится ли данный guard-page на который нечаянно наступили, к какому-нибудь еще стеку, что действительно довольно тупо. Опять же, если продвинутый пользователь желает использовать guard-pages сам для своих собственных структур данных (а не для стека треда), то чужой тред снова имеет чудесную возможность долбануть по этому guard-page, получить исключение и поднять лапки кверху, поскольку что делать с этим исключением он не знает.
В общем, весь концепт guard-page задизайнен, похож, немного криво.
----------------------------------
С другой стороны, как отмечают тут (ссылка аж с 2003-го года!) память может быть замаплена и на порты ввода-вывода устройств, и тут уже остается не жаловаться на кривой дизайн или имлементацию guard-page, а просто, видимо, обозначить, что lock-free синхронизацию принципиально нельзя делать без поддержки сборщика мусора (которому самому желательно быть lock-free :-))) или рецайлинга объектов (даже не памяти, а именно объектов, чтобы будущие адресации нечаянно не попали на переалллоцированный объект другого формата).
Вроде, подобные мысли время от времени попадались, но не так чтобы где-то я видел их четко и однозначно сформулированными. Надо будет что-нидь перечитать по теме.
--------------------
UPD: перечитал. был неправ. можно память и освобождать. без сборщика мусора. и без рецайклинга. но аккуратно. )))
http://groups.google.com/group/lock-free/browse_thread/thread/d7ac22f807d1d439
Возможно и похоже (я не проверял, у меня сейчас на виндах нет ни дебаггера ни даже С++, а дискуссия по ссылке чуток неадеквата), что сейчас под виндоуз невозможно написать 100% надёжный lock-free код, возвращающий память системе с помощью вызова free и подобного, а не возвращающий выделенную память в пул, либо использующий сборщик мусора.
Причина несколько тонка - в результате освобождения памяти может произойти исключение при доступе по "старому" указателю. Само по себе это не беда - можно надеяться словить исключение и обработать его как факт того, что указатель устарел.
Проблема, однако, в том, что адресуясь по устаревшим указателям наугад можно нечаянно задеть guard-page другого треда, а это, как это не смешно, приводит через непродолжительное время к терминации процесса.
Т.е. я опять ж не проверял, но не исключено, что функция InterlockedPopEntrySList имеет неустранимый, в рамках старого ядра виндов, баг.
Вообще, чего б этому самому ядру не заботиться о том, чтобы не сносить аттрибут guard-pages если они не относятся к стеку текущего треда? Ведь уже так или иначе исключение по доступу к guard page стека делается в kernel-mode, так отчего бы и нет? Впрочем, тогда либо придется вводить дополнительный аттрибут памяти "stack guard page", либо тупо проверять, а не относится ли данный guard-page на который нечаянно наступили, к какому-нибудь еще стеку, что действительно довольно тупо. Опять же, если продвинутый пользователь желает использовать guard-pages сам для своих собственных структур данных (а не для стека треда), то чужой тред снова имеет чудесную возможность долбануть по этому guard-page, получить исключение и поднять лапки кверху, поскольку что делать с этим исключением он не знает.
В общем, весь концепт guard-page задизайнен, похож, немного криво.
----------------------------------
С другой стороны, как отмечают тут (ссылка аж с 2003-го года!) память может быть замаплена и на порты ввода-вывода устройств, и тут уже остается не жаловаться на кривой дизайн или имлементацию guard-page, а просто, видимо, обозначить, что lock-free синхронизацию принципиально нельзя делать без поддержки сборщика мусора (которому самому желательно быть lock-free :-))) или рецайлинга объектов (даже не памяти, а именно объектов, чтобы будущие адресации нечаянно не попали на переалллоцированный объект другого формата).
Вроде, подобные мысли время от времени попадались, но не так чтобы где-то я видел их четко и однозначно сформулированными. Надо будет что-нидь перечитать по теме.
--------------------
UPD: перечитал. был неправ. можно память и освобождать. без сборщика мусора. и без рецайклинга. но аккуратно. )))