Привет Всемогущий All.
Есть задача производитель/потребитель в многопоточном режиме (один поток производитель, другой потребитель) с lockfree очередью. Нужно сделать, чтобы потребитель мог отправиться спать при отсутствии задач в очереди, а производитель мог его разбудить, когда появились новые задачи и хоть один потребитель спит (тех и других может быть по несколько потоков). Очередь lockfree, поэтому в нагруженном режиме (в очереди есть задачи, все потребители работают) все должно работать без блокировок. Условные переменные не подходят, т.к. notify() из производителя хоть и можно делать без блокировки, но он легко может вклиниться между проверкой потребителем очереди и засыпанием...
В Linux есть замечательное средство - FUTEX(2) (сколько бы в его man'е не пугали, что его осилит только избранный, в реальности все довольно просто с атомарными переменными), даже в Windows(8/2012) есть WaitOnAddress (правда со своими особенностями). Библиотеку хочется сделать кроссплатформенной, поэтому осталось определиться с третьей Os, которая имеет хоть какое-то значение для релизации - Mac (BSD).
Суть реализации в Linux (и Windows) в том, что поток заснет только при условии, что переменная (int) выставлена в определенное значение, поэтому для notify() нужно изменить ее значение на «не спать», после этого никто не уснет, и сделать FUTEX_WAKE, чтобы кто-нибудь проснулся (возможно, проснется один + кто-то не заснет, но хоть один, все же проснется). В результате засыпание/пробуждение получается сделать без гонок и блокировок (отсутствие блокировок важно только в нагруженном режиме, т.к. если начались засыпания, то потокам нечего делать и дополнительные расходы значения не имеют - потоки и так бездельничают).
Вопрос, какой есть аналог Futex в ядре BSD (кроме эмуляции Linux) для реализации такой задачи?