Re[2]: Fixed: Interlocked Circle Buffer
От: Caracrist https://1pwd.org/
Дата: 07.03.10 09:42
Оценка: 40 (1)
Здравствуйте, Caracrist, Вы писали:

Нашел маленький oops ,

        template<typename T>
        class interlocked_circle_buffer
        {
        protected:
            enum cell_status_enum 
            {
                cell_Free = 0,
                cell_Written,
                cell_Full,
                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(-1),
                m_reading(-1),
                m_read(0),
                m_written(0),
                m_filled(0),
                m_filling(0)
                {}
            ~interlocked_circle_buffer(){delete [] m_buffer;}
            bool push(const T& value)
            {
                if (InterlockedIncrement(&m_filling) > m_size)
                {
                    InterlockedDecrement(&m_filling);
                    return false;
                }
                long write = InterlockedIncrement(&m_writing) % m_size;
                m_buffer[write].data = value; 
                m_buffer[write].status = cell_Written;
                finalize_write();
                return true;
            }
            bool pop(T * target)
            {
                if (InterlockedDecrement(&m_filled) < 0)
                {
                    InterlockedIncrement(&m_filled);
                    return false;
                }
                long read = InterlockedIncrement(&m_reading) % m_size;
                *target = m_buffer[read].data;
                m_buffer[read].status = cell_Read;
                finalize_read();
                return true;
            }
        private:
            void finalize_read()
            {
                while (true)
                {
                    long read = InterlockedExchange(&m_read, -1);
                    if (read != -1)
                    //if (long read = InterlockedExchange(&m_read, -1) != -1) // oops 
                    {
                        if (InterlockedCompareExchange(&m_buffer[read].status, cell_Free, cell_Read) == cell_Read)
                        {
                            m_read = (read + 1) % m_size;
                            InterlockedDecrement(&m_filling);
                            continue;
                        }
                        else 
                        {
                            m_read = read;
                            if (InterlockedCompareExchange(&m_buffer[read].status, cell_Read, cell_Read) == cell_Read)
                                continue;
                        }
                    }
                    break;
                }
                if (m_reading > MAXLONG / 2)
                    InterlockedOperation(&m_reading, x % m_size);
            }
            void finalize_write()
            {
                while (true)
                {
                    long write = InterlockedExchange(&m_written, -1);
                    if (write != -1)
                    //if (long write = InterlockedExchange(&m_written, -1) != -1) // oops 
                    {
                        if (InterlockedCompareExchange(&m_buffer[write].status, cell_Full, cell_Written) == cell_Written)
                        {
                            m_written = (write + 1) % m_size;
                            InterlockedIncrement(&m_filled);
                            continue;
                        }
                        else 
                        {
                            m_written = write;
                            if (InterlockedCompareExchange(&m_buffer[write].status, cell_Written, cell_Written) == cell_Written)
                                continue;
                        }
                    }
                    break;
                }
                if (m_writing > MAXLONG / 2)
                    InterlockedOperation(&m_writing, x % m_size);
            }
        protected: // member fields
            cell_struct * m_buffer;
            long m_size;
            volatile long m_writing, m_reading
                , m_written, m_read
                , m_filling, m_filled;

        };
~~~~~
~lol~~
~~~ Single Password Solution
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.