Операция сигнала (которую вы называете уведомлением) не должна требовать ввода монитора. Это неэффективно.
Похоже, вы пытаетесь реализовать какую-то неуклюжую старомодную систему состояния / монитора, в которой вызывающий «уведомлять» должен находиться внутри монитора, и гарантируется, что, если поток ожидает, этот поток получает монитор до того, как «уведомить», вызывающий абонент возвращается к монитору. (И этот ожидающий поток также не должен иметь цикл, повторно проверяющий условие.)
Это может быть, как CAR Hoare первоначально описал мониторы и условия, но формализм нецелесообразен / неэффективен для современных многопроцессорных систем, а также для потоковых реализаций, которые не имеют такой роскоши, как чрезвычайно тесная интеграция с планировщиком низкого уровня (для иметь возможность точно контролировать, какой поток должен запускаться, когда нет, поэтому нет никаких гонок о том, кто первым получает мьютекс: например, чтобы иметь возможность передавать поток из одной очереди ожидания в другую и т. д.)
Обратите внимание, как вы расширяете критическую секцию монитора в операции spinlock_lock
и операции dequeue
. Ни один из них не относится к монитору. Спин-блокировка независима, и очередь защищена спин-блокировкой, а не монитором. Монитор должен защищать только общие переменные пользовательского кода (специальное атомарное свойство операции ожидания).