Re: Возможный косяк в boost::mutex
От: fdn721  
Дата: 14.04.11 06:55
Оценка: +1
Здравствуйте, ioni, Вы писали:

I>Рассмотрим реализацию boost::mutex (последняя версия)


I>
I>            bool timed_lock(::boost::system_time const& wait_until)
I>            {
I>(1)                if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
I>                {
I>                    return true;
I>                }
I>                long old_count=active_count;
I>(2)                for(;;)
I>                {
I>                    long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
I>                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
I>                    if(current==old_count)
I>                    {
I>                        break;
I>                    }
I>                    old_count=current;
I>                }

I>                if(old_count&lock_flag_value)
I>                {
I>                    bool lock_acquired=false;
I>                    void* const sem=get_event();

I>                    do
I>                    {
I>(3)                        if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
I>                        {
I>                            BOOST_INTERLOCKED_DECREMENT(&active_count);
I>                            return false;
I>                        }
I>                        old_count&=~lock_flag_value;
I>                        old_count|=event_set_flag_value;
I>                        for(;;)
I>                        {
I>                            long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
I>                            long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
I>                            if(current==old_count)
I>                            {
I>                                break;
I>                            }
I>                            old_count=current;
I>                        }
I>                        lock_acquired=!(old_count&lock_flag_value);
I>                    }
I>                    while(!lock_acquired);
I>                }
I>                return true;
I>            }

I>            void unlock()
I>            {
I>                long const offset=lock_flag_value;
I>(4)                long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
I>                if(!(old_count&event_set_flag_value) && (old_count>offset))
I>                {
I>(5)                    if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
I>                    {
I>                        win32::SetEvent(get_event());
I>                    }
I>                }
I>            }
I>


I>рассмотрим такую ситуацию

I>Имеем три потока с приоритетами Low, Medium, High
I>в начальном состоянии поток Low захватил mutex в точке 1 потому что он первый,
I>далее начинает работать стартует поток Medium система передает ему управление так как он имеет более высокий приоритет
I>потом начинает работать поток High и пытается захватить mutex, так как mutex уже захвачен доходит до точки 3 и ждет
I>так как поток High ждет, управление передается потоку Medium и пока он не отработает не произойдет инверсии приоритета для
I>потока Low и поток High не получит управления.
I>Вот такая дыра обнаружилась

Что-то у вас какое-то мутное представление о приоритете потоков.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.