123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- #ifndef __TBB_concurrent_queue_H
- #define __TBB_concurrent_queue_H
- #include "internal/_concurrent_queue_impl.h"
- namespace tbb {
- namespace strict_ppl {
- template<typename T, typename A = cache_aligned_allocator<T> >
- class concurrent_queue: public internal::concurrent_queue_base_v3<T> {
- template<typename Container, typename Value> friend class internal::concurrent_queue_iterator;
-
- typedef typename A::template rebind<char>::other page_allocator_type;
- page_allocator_type my_allocator;
-
- virtual void *allocate_block( size_t n ) {
- void *b = reinterpret_cast<void*>(my_allocator.allocate( n ));
- if( !b )
- internal::throw_exception(internal::eid_bad_alloc);
- return b;
- }
-
- virtual void deallocate_block( void *b, size_t n ) {
- my_allocator.deallocate( reinterpret_cast<char*>(b), n );
- }
- public:
-
- typedef T value_type;
-
- typedef T& reference;
-
- typedef const T& const_reference;
-
- typedef size_t size_type;
-
- typedef ptrdiff_t difference_type;
-
- typedef A allocator_type;
-
- explicit concurrent_queue(const allocator_type& a = allocator_type()) :
- my_allocator( a )
- {
- }
-
- template<typename InputIterator>
- concurrent_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) :
- my_allocator( a )
- {
- for( ; begin != end; ++begin )
- this->internal_push(&*begin);
- }
-
-
- concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) :
- internal::concurrent_queue_base_v3<T>(), my_allocator( a )
- {
- this->assign( src );
- }
-
-
- ~concurrent_queue();
-
- void push( const T& source ) {
- this->internal_push( &source );
- }
-
-
- bool try_pop( T& result ) {
- return this->internal_try_pop( &result );
- }
-
- size_type unsafe_size() const {return this->internal_size();}
-
- bool empty() const {return this->internal_empty();}
-
- void clear() ;
-
- allocator_type get_allocator() const { return this->my_allocator; }
- typedef internal::concurrent_queue_iterator<concurrent_queue,T> iterator;
- typedef internal::concurrent_queue_iterator<concurrent_queue,const T> const_iterator;
-
-
-
- iterator unsafe_begin() {return iterator(*this);}
- iterator unsafe_end() {return iterator();}
- const_iterator unsafe_begin() const {return const_iterator(*this);}
- const_iterator unsafe_end() const {return const_iterator();}
- } ;
- template<typename T, class A>
- concurrent_queue<T,A>::~concurrent_queue() {
- clear();
- this->internal_finish_clear();
- }
- template<typename T, class A>
- void concurrent_queue<T,A>::clear() {
- while( !empty() ) {
- T value;
- this->internal_try_pop(&value);
- }
- }
- }
-
- template<typename T, class A = cache_aligned_allocator<T> >
- class concurrent_bounded_queue: public internal::concurrent_queue_base_v3 {
- template<typename Container, typename Value> friend class internal::concurrent_queue_iterator;
-
- typedef typename A::template rebind<char>::other page_allocator_type;
- page_allocator_type my_allocator;
- typedef typename concurrent_queue_base_v3::padded_page<T> padded_page;
-
-
- class destroyer: internal::no_copy {
- T& my_value;
- public:
- destroyer( T& value ) : my_value(value) {}
- ~destroyer() {my_value.~T();}
- };
- T& get_ref( page& p, size_t index ) {
- __TBB_ASSERT( index<items_per_page, NULL );
- return (&static_cast<padded_page*>(static_cast<void*>(&p))->last)[index];
- }
- virtual void copy_item( page& dst, size_t index, const void* src ) {
- new( &get_ref(dst,index) ) T(*static_cast<const T*>(src));
- }
- virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) {
- new( &get_ref(dst,dindex) ) T( get_ref( const_cast<page&>(src), sindex ) );
- }
- virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) {
- T& from = get_ref(src,index);
- destroyer d(from);
- *static_cast<T*>(dst) = from;
- }
- virtual page *allocate_page() {
- size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T);
- page *p = reinterpret_cast<page*>(my_allocator.allocate( n ));
- if( !p )
- internal::throw_exception(internal::eid_bad_alloc);
- return p;
- }
- virtual void deallocate_page( page *p ) {
- size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T);
- my_allocator.deallocate( reinterpret_cast<char*>(p), n );
- }
- public:
-
- typedef T value_type;
-
- typedef A allocator_type;
-
- typedef T& reference;
-
- typedef const T& const_reference;
-
-
- typedef std::ptrdiff_t size_type;
-
- typedef std::ptrdiff_t difference_type;
-
- explicit concurrent_bounded_queue(const allocator_type& a = allocator_type()) :
- concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
- {
- }
-
- concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type()) :
- concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
- {
- assign( src );
- }
-
- template<typename InputIterator>
- concurrent_bounded_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) :
- concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
- {
- for( ; begin != end; ++begin )
- internal_push_if_not_full(&*begin);
- }
-
- ~concurrent_bounded_queue();
-
- void push( const T& source ) {
- internal_push( &source );
- }
-
-
- void pop( T& destination ) {
- internal_pop( &destination );
- }
- #if TBB_USE_EXCEPTIONS
-
- void abort() {
- internal_abort();
- }
- #endif
-
-
- bool try_push( const T& source ) {
- return internal_push_if_not_full( &source );
- }
-
-
- bool try_pop( T& destination ) {
- return internal_pop_if_present( &destination );
- }
-
-
- size_type size() const {return internal_size();}
-
- bool empty() const {return internal_empty();}
-
- size_type capacity() const {
- return my_capacity;
- }
-
-
- void set_capacity( size_type new_capacity ) {
- internal_set_capacity( new_capacity, sizeof(T) );
- }
-
- allocator_type get_allocator() const { return this->my_allocator; }
-
- void clear() ;
- typedef internal::concurrent_queue_iterator<concurrent_bounded_queue,T> iterator;
- typedef internal::concurrent_queue_iterator<concurrent_bounded_queue,const T> const_iterator;
-
-
-
- iterator unsafe_begin() {return iterator(*this);}
- iterator unsafe_end() {return iterator();}
- const_iterator unsafe_begin() const {return const_iterator(*this);}
- const_iterator unsafe_end() const {return const_iterator();}
- };
- template<typename T, class A>
- concurrent_bounded_queue<T,A>::~concurrent_bounded_queue() {
- clear();
- internal_finish_clear();
- }
- template<typename T, class A>
- void concurrent_bounded_queue<T,A>::clear() {
- while( !empty() ) {
- T value;
- internal_pop_if_present(&value);
- }
- }
- namespace deprecated {
- template<typename T, class A = cache_aligned_allocator<T> >
- class concurrent_queue: public concurrent_bounded_queue<T,A> {
- #if !__TBB_TEMPLATE_FRIENDS_BROKEN
- template<typename Container, typename Value> friend class internal::concurrent_queue_iterator;
- #endif
- public:
-
- explicit concurrent_queue(const A& a = A()) :
- concurrent_bounded_queue<T,A>( a )
- {
- }
-
- concurrent_queue( const concurrent_queue& src, const A& a = A()) :
- concurrent_bounded_queue<T,A>( src, a )
- {
- }
-
- template<typename InputIterator>
- concurrent_queue( InputIterator b /*begin*/, InputIterator e /*end*/, const A& a = A()) :
- concurrent_bounded_queue<T,A>( b, e, a )
- {
- }
-
-
- bool push_if_not_full( const T& source ) {
- return this->try_push( source );
- }
-
-
- bool pop_if_present( T& destination ) {
- return this->try_pop( destination );
- }
- typedef typename concurrent_bounded_queue<T,A>::iterator iterator;
- typedef typename concurrent_bounded_queue<T,A>::const_iterator const_iterator;
-
-
-
-
- iterator begin() {return this->unsafe_begin();}
- iterator end() {return this->unsafe_end();}
- const_iterator begin() const {return this->unsafe_begin();}
- const_iterator end() const {return this->unsafe_end();}
- };
- }
-
- #if TBB_DEPRECATED
- using deprecated::concurrent_queue;
- #else
- using strict_ppl::concurrent_queue;
- #endif
- }
- #endif
|