Refcount strikes back

топ 100 блогов dz01.09.2011 Помощь клуба? Под кат имеет смысл глядеть, если refcount gc - не пустой звук.

Дано: "короткий" GC в Фантоме - на счётчиках ссылок. (Я знаю его ограничения, это нормально.) Недавно в нём была поймана бага вида races, и крайне злая.

- дано - объект и его поле. Поле хранит пойнтер на другой объект.
- при записи в поле происходит декремент рефкаунтера предыдущего значения поля (если оно не нулевое) - что логично. Ссылку потеряли - каунтер декрементим.
- при чтении поля надо бы каунтер инкрементить, но тут и возникает race. По шагам:

1. тред 2 читает значение поля.
-- свитч треда
2. тред 1 стирает поле и декрементит каунтер. объект весело идёт в могилу.
-- тайм пассез, свитч треда
3. тред 2 пытается проинкрементить и взрывает чей-то мозг, потому что объект давно уже склеили с пустым местом и кому-то выделили это место. Ну, короче, нехорошо получается.

Напрашивается спинлок вокруг рефкаунтера, но закрывать спинлок на каждое считывание поля - это просто беда. Оч. дорого.

Есть ещё идея - все декременты и инкременты делать отложенно - класть пойнтер на объект в очередь инкремента и декремента, и потом отрабатывать их в порядке "сначала все инкременты". Это гарантирует, насколько я вижу, непотерю объекта, да и выполнить эти операции можно в idle time, условно бесплатно. Но нагрузка в сумме всё равно получится немалая, да и это приведёт к тому, что пиковое потребление памяти вырастет, или же придётся, всё равно, делать разгрузку очереди не только в idle time.

Может, есть ещё идеи, которые мне не видны навскидку? Простая оптимизация - делать инкремент инлайн, а декремент отложенно - увы, ни фига не гарантирует.

Впрочем, только что осознал, что и схема с очередями не гарантирует - всё равно нужна атомарность по считыванию пойнтера и инкременту, ядри её в корень. (просто схлопывание очередей может оказаться в позиции 2 выше и вызвать ту же проблему.)

Или есть путь без?

PS: Если вам кажется, что atomic inc - это ответ на вопрос, то вы невнимательно прочитали вопрос.

Оставить комментарий

Предыдущие записи блогера :
Архив записей в блогах:
Никогда не смешивайте водку с пивом. Пиво будет звать вас в туалет, а водка лишит возможности дойти туда.... ...
Я рос в довольно пролетарском районе Новосибирска, и с гопниками мне приходилось сталкиваться с детства. «Сталкиваться» – не очень подходящее слово, скорее, гопники были некой местной элитой и задавали порядки поведения на районе. Если группа гопников вступила с тобой в диалог, дело, ...
Полиция Таиланда задержала сегодня (11 июля) грузовик с 90 кошками, которых, предположительно, везли во Вьетнам, передает агентство АР со ссылкой на местную полицию. Водитель задержанного грузовика рассказал полиции, что ему заплатили примерно 63 доллара за то, чтобы он довез кошек до ...
Вполне возможно, что многие из вас знакомы с некоторыми из этих снимков, однако скорее всего кое-что вы увидите впервые. Во-первых, они все цветные. А во-вторых, сделаны так, что буквально погружают в ту аутентичную атмосферу. Полное ощущение путешествия во времени на 60-70 лет назад. ...
Считается - что назвать другого человека животным это оскорбление. Хотя на самом деле, вовсе не каждый двуногий достоин стоять на одной ступени с кошкой или собакой У меня всю жизнь жили кошки. Разные с ними складывались отношения, но кошка всегда рядом когда болеешь со своим нехитрым ...