Interlocked Circle Buffer
От: Caracrist http://1pwd.org/
Дата: 05.03.10 12:05
Оценка:


        template<typename T>
        class interlocked_circle_buffer
        {
        protected:
            enum cell_status_enum 
            {
                cell_Free = 0,
                cell_Filling,
                cell_Full,
                cell_Reading,
                cell_Read
            };
            struct cell_struct    {
                volatile long status;
                T data;
                cell_struct(): status(cell_Free){}
            };
        public:
            interlocked_circle_buffer(size_t size) : 
                m_size(size),
                m_buffer(new cell_struct[size]),
                m_writing(0),
                m_reading(0),
                m_read(0)
                {}
            ~interlocked_circle_buffer(){delete [] m_buffer;}
            bool push(const T& value)
            {
                long write;
                bool searching = true;
                while (searching)
                {
                    write = m_writing;
                    long cellStatus = InterlockedCompareExchange(&m_buffer[write].status, cell_Filling, cell_Free);
                    switch (cellStatus)
                    {
                        case cell_Free:
                            searching = false;
                        case cell_Filling:
                            InterlockedCompareExchange(&m_writing, (write+1) % m_size, write);
                            break;
                        default:
                            return false;
                    }            
                }
                m_buffer[write].data = value; 
                m_buffer[write].status = cell_Full;
                return true;
            }
            bool pop(T * target)
            {
                long read;
                bool searching = true;
                while (searching)
                {
                    read = m_reading;
                    long cellStatus = InterlockedCompareExchange(&m_buffer[read].status, cell_Reading, cell_Full);
                    switch (cellStatus)
                    {
                    case cell_Full:
                        searching = false;
                    case cell_Reading:
                    case cell_Read:
                        InterlockedCompareExchange(&m_reading, (read+1) % m_size, read);
                        break;
                    default:
                        return false;
                    }
                }
                *target = m_buffer[read].data;
                m_buffer[read].status = cell_Read;
                if (InterlockedCompareExchange(&m_read, (read+1) % m_size, read) == read)
                {
                    while (InterlockedCompareExchange(&m_buffer[read].status, cell_Free, cell_Read) == cell_Read)
                    {
                        if (InterlockedCompareExchange(&m_read, (read+1) % m_size, read) != read)
                            break;
                        read = (read+1) % m_size;
                    }
                }
                return true;
            }
        protected: // member fields
            cell_struct * m_buffer;
            size_t m_size;
            volatile long m_writing, m_reading, m_read;
        };

~~~~~
~lol~~
~~~ Cracked Minds (головоломки)
[c++][threads][src]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.