/** * Set the data to a certain value (non blocking). * * @param push The data which must be set. */ virtual void Set( const DataType& push ) { /** * This method can not be called concurrently (only one * producer). With a minimum of 3 buffers, if the * write_ptr+1 field is not occupied, it will remain so * because the read_ptr is at write_ptr-1 (and can * not increment the counter on write_ptr+1). Hence, no * locking is needed. */ // writeout in any case write_ptr->data = push; PtrType wrote_ptr = write_ptr; // if next field is occupied (by read_ptr or counter), // go to next and check again... while ( oro_atomic_read( &write_ptr->next->counter ) != 0 || write_ptr->next == read_ptr ) { write_ptr = write_ptr->next; if (write_ptr == wrote_ptr) return; // nothing found, to many readers ! } // we will be able to move, so replace read_ptr read_ptr = wrote_ptr; write_ptr = write_ptr->next; // we checked this in the while loop }
/** * Increase the reference count of a piece of memory. * Returns false if already released. */ bool lock(pointer m) { Item* it = reinterpret_cast<Item*>(m); if ( oro_atomic_read(&it->rc) == 0 ) return false; oro_atomic_inc(&(it->rc) ); return true; }
/** * Decrease the reference count of a piece of memory \a m, * which becomes available for allocation. */ bool deallocate( pointer m ) { Item* it = reinterpret_cast<Item*>(m); if ( oro_atomic_read(&it->rc) == 0 ) return false; if( oro_atomic_dec_and_test( &(it->rc) ) ) if ( mpool.enqueue( static_cast<void*>(m) ) == false ) assert(false && "Deallocating more elements than allocated !"); return true; }
/** * Deallocate and unlock() a piece of memory. * Returns false if already released. */ bool deallocate( pointer m ) { Item* item = reinterpret_cast<Item*>(m); if ( oro_atomic_read(&item->rc) == 0 ) return false; if( oro_atomic_dec_and_test( &(item->rc) ) ) { for ( typename PoolType::iterator it = mpool.begin(); it != mpool.end(); ++it ) { if ( it->first->enqueue( static_cast<void*>(m) ) ) { return true; } } assert(false && "Deallocating more elements than allocated !"); } return true; }
/** * Read the current value of the integer. */ int read() const { return oro_atomic_read( &_val); }
const AtomicInt& operator=(const AtomicInt& orig) { oro_atomic_set( &_val, oro_atomic_read( &(orig._val))); return *this; }
AtomicInt(const AtomicInt& orig) { ORO_ATOMIC_SETUP( &_val, oro_atomic_read( &(orig._val) ) ); }
/** * Returns how many times a piece of memory * is used. */ size_type useCount( pointer m ) { return oro_atomic_read( &static_cast< Item* >(m)->rc ); }