Re[2]: Atomics в gcc 4.6 в c++0x
От: anton_p  
Дата: 18.05.11 14:56
Оценка: 1 (1)
Здравствуйте, TarasKo, Вы писали:

есть вопрос и несколько предложений.
1. какая архитектура ? x86 ?
для проверки самого алгоритма можно:
2. переписать код с использоанием TBB атомиков (http://threadingbuildingblocks.org/files/documentation/a00117.html)
3. попробовать Relacy Race Detector (http://www.1024cores.net/home/relacy-race-detector), там ксати вроде как и реализация С++0х атомиков есть тоже, можно ее попробовать

4. ИМХО в кодe метода pop есть шанс (хоть и маловероятный) бесконечного роста списка к удалению (to_be_deleted_). Сценарий такой:
1. первый поток, уменьшая счетчик потоков, входит в ветку if и засыпает
2. второй поток входит в pop (увеличивая счетчик потоков) и засыпает
3. третий поток входит в pop (увеличивая счетчик потоков), заходит в вветку else и меняет to_be_deleted_
4. первый поток просыпается, проваливается на compare_exchange (выделено жирным), и выходит

теоритически, такая последовательность может, повторяться бесконечное число раз, приводя к бесконечному накапливанию памяти.
   
    std::shared_ptr<T> pop()
    {
        ++threads_in_pop_;
        
        node* old_head = head_.load();
        while(old_head && !head_.compare_exchange_strong(old_head, old_head->next_));

        std::shared_ptr<T> res;
        if (old_head)
            res.swap(old_head->data_);
                
        node* nodes_to_delete = to_be_deleted_.load();
        
        if (!--threads_in_pop_)
        {
            if (to_be_deleted_.compare_exchange_strong(nodes_to_delete, 0))  
                delete_nodes(nodes_to_delete);
            
            delete old_head; 
        }
        else if (old_head)
        {
            old_head->next_ = nodes_to_delete;
            while(!to_be_deleted_.compare_exchange_weak(old_head->next_, old_head)); 
        }
        
        return res;
    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.