24 #define _SCL_SECURE_NO_WARNINGS 36 #if defined(_MSC_VER) && defined(_Wp64) 38 #pragma warning (disable: 4267) 50 return size < page_size || ((size-1)%page_size < page_size/2 && size < page_size * 128);
86 template<
typename argument_type>
133 if( k < first_block ) k = 0;
136 finish -= base; start -= base;
140 finish -=
sz; start = 0;
147 while( sz < finish ) {
149 func( table[k], table[k].load<relaxed>().pointer<char>() + element_size*start, sz - start );
152 func( table[k], table[k].load<relaxed>().pointer<char>() + element_size*start, finish - start );
165 if( sz >= finish )
return;
178 func( begin, arg, n );
187 func( begin, arg, n );
216 __TBB_ASSERT(new_segment_table,
"NFS_Allocate should throws exception if it cannot allocate the requested storage, and not returns zero pointer" );
227 bool mark_as_not_used_on_failure ) {
229 struct segment_scope_guard :
no_copy{
231 bool my_mark_as_not_used;
232 segment_scope_guard(
segment_t& segment,
bool mark_as_not_used) : my_segment_ptr(&segment), my_mark_as_not_used(mark_as_not_used){}
233 void dismiss(){ my_segment_ptr = 0;}
234 ~segment_scope_guard(){
236 if (!my_mark_as_not_used){
249 size_type size_to_allocate = size_of_enabled_segment;
252 size_of_enabled_segment = 2 ;
270 segment_scope_guard k_segment_guard(s[k],
false);
272 k_segment_guard.dismiss();
278 segment_scope_guard k_segment_guard(s[k], mark_as_not_used_on_failure);
280 k_segment_guard.dismiss();
282 return size_of_enabled_segment;
290 if( k_start < first_block ) {
294 for(; k_start < first_block && k_start <= k_end; ++k_start )
296 else for(; k_start < first_block && k_start <= k_end; ++k_start )
300 for(; k_start <= k_end; ++k_start )
307 while( sz <= finish ) {
373 if( m > n-b ) m = n-b;
407 if( m > n-b ) m = n-b;
409 if( dst_initialized_size>b ) {
410 a = dst_initialized_size-b;
419 __TBB_ASSERT( src.
my_early_size==n,
"detected use of concurrent_vector::operator= with right side that was concurrently modified" );
431 return (
void*)(s.
load<
relaxed>().pointer<char>() + element_size*j_begin);
440 while( e<new_size ) {
453 for( i = 0; i <= k_old; ++i ) {
473 internal_grow( result, result+delta, element_size, init, src );
478 __TBB_ASSERT( start<finish,
"start must be less than finish" );
483 for(; k_end > k_start && k_end >= range.
first_block; --k_end )
485 for(; k_start <= k_end; ++k_start )
512 return j < i? i : j+1;
523 if(k_stop < first_block)
527 if(k_stop == k_end && k == first_block)
536 if ( k != first_block && k )
544 for (
segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) {
546 void *
s =
static_cast<void*
>(
549 if(j + my_segment_size >= my_size) my_segment_size = my_size - j;
551 copy( s, segment_table[i].load<relaxed>().pointer<void>(), my_segment_size );
561 std::copy(segment_table,segment_table + k,old.
table);
569 for (
segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) {
570 if(j + my_segment_size >= my_size) my_segment_size = my_size - j;
577 if ( k_stop < k_end ) {
579 std::copy(segment_table+k_stop, segment_table+k_end, old.
table+k_stop );
580 std::fill_n(segment_table+k_stop, (k_end-k_stop),
segment_t());
590 if(!my_sz && !v_sz)
return;
Internal structure for compact()
static segment_t & acquire_segment(concurrent_vector_base_v3 &v, size_type index, size_type element_size, bool owner)
static void publish_segment(segment_t &s, argument_type rhs)
Publish segment so other threads can see it.
static void assign_first_segment_if_necessary(concurrent_vector_base_v3 &v, segment_index_t k)
assign first segment size. k - is index of last segment to be allocated, not a count of segments ...
Class that implements exponential backoff.
void *__TBB_EXPORTED_FUNC NFS_Allocate(size_t n_element, size_t element_size, void *hint)
Allocate memory on cache/sector line boundary.
Base class of concurrent vector implementation.
segment_t table[pointers_per_long_table]
size_type __TBB_EXPORTED_METHOD internal_grow_by(size_type delta, size_type element_size, internal_array_op2 init, const void *src)
void __TBB_EXPORTED_METHOD internal_throw_exception(size_type) const
Obsolete.
void cleanup()
Out of line code to assists destructor in infrequent cases.
void operator()(segment_t &s, void *begin, size_type n) const
#define __TBB_STATIC_ASSERT(condition, msg)
atomic< size_type > my_first_block
count of segments in the first block
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
static bool incompact_predicate(size_type size)
Base class for types that should not be assigned.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp begin
size_type __TBB_EXPORTED_METHOD internal_capacity() const
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t new_size
segment_t my_storage[pointers_per_short_table]
embedded storage of segment pointers
void __TBB_EXPORTED_METHOD internal_swap(concurrent_vector_base_v3 &v)
void *__TBB_EXPORTED_METHOD internal_push_back(size_type element_size, size_type &index)
init_body(internal_array_op2 init, const void *src)
size_type apply(const F &func)
helper(segment_t *segments, size_type fb, size_type esize, size_type index, size_type s, size_type f)
segment_index_t __TBB_EXPORTED_METHOD internal_clear(internal_array_op1 destroy)
static segment_index_t segment_index_of(size_type index)
static void extend_table_if_necessary(concurrent_vector_base_v3 &v, size_type k, size_type start)
static size_type segment_size(segment_index_t k)
atomic< size_type > my_early_size
Requested size of vector.
segment_index_t first_block
void throw_exception(exception_id eid)
Versionless convenience wrapper for throw_exception_v4()
void __TBB_EXPORTED_METHOD internal_copy(const concurrent_vector_base_v3 &src, size_type element_size, internal_array_op2 copy)
destroy_body(internal_array_op1 destroy)
__TBB_EXPORTED_METHOD ~concurrent_vector_base_v3()
void __TBB_EXPORTED_METHOD internal_grow_to_at_least(size_type new_size, size_type element_size, internal_array_op2 init, const void *src)
Deprecated entry point for backwards compatibility to TBB 2.1.
friend void enforce_segment_allocated(segment_value_t const &s, internal::exception_id exception=eid_bad_last_alloc)
static segment_index_t segment_base(segment_index_t k)
value_type compare_and_swap(value_type value, value_type comparand)
void internal_grow(size_type start, size_type finish, size_type element_size, internal_array_op2 init, const void *src)
void __TBB_EXPORTED_METHOD internal_assign(const concurrent_vector_base_v3 &src, size_type element_size, internal_array_op1 destroy, internal_array_op2 assign, internal_array_op2 copy)
static const size_type page_size
memory page size
void spin_wait_while_eq(const volatile T &location, U value)
Spin WHILE the value of the variable is equal to a given value.
TODO: turn into lambda functions when available.
void(__TBB_EXPORTED_FUNC * internal_array_op2)(void *dst, const void *src, size_type n)
An operation on n-element destination array and n-element source array.
friend void swap(segment_t &, segment_t &) __TBB_NOEXCEPT(true)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p sync_releasing
segment_not_used_predicate(segment_t &segment)
void store(value_type value)
static size_type enable_segment(concurrent_vector_base_v3 &v, size_type k, size_type element_size, bool mark_as_not_used_on_failure=false)
#define ITT_NOTIFY(name, obj)
void *(* vector_allocator_ptr)(concurrent_vector_base_v3 &, size_t)
allocator function pointer
void const char const char int ITT_FORMAT __itt_group_sync s
void spin_wait_while(predicate_type condition)
void(__TBB_EXPORTED_FUNC * internal_array_op1)(void *begin, size_type n)
An operation on an n-element array starting at begin.
void __TBB_EXPORTED_METHOD internal_resize(size_type n, size_type element_size, size_type max_size, const void *src, internal_array_op1 destroy, internal_array_op2 init)
segment_value_t get_segment_value(size_type index, bool wait)
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void *__TBB_EXPORTED_METHOD internal_compact(size_type element_size, void *table, internal_array_op1 destroy, internal_array_op2 copy)
void operator()(segment_t &, void *begin, size_type n) const
static void * allocate_segment(concurrent_vector_base_v3 &v, size_type n)
Base class for types that should not be copied or assigned.
void store(segment_not_used)
size_type __TBB_EXPORTED_METHOD internal_grow_to_at_least_with_result(size_type new_size, size_type element_size, internal_array_op2 init, const void *src)
segment_value_t load() const
static void extend_segment_table(concurrent_vector_base_v3 &v, size_type start)
void __TBB_EXPORTED_METHOD internal_reserve(size_type n, size_type element_size, size_type max_size)
static size_type find_segment_end(const concurrent_vector_base_v3 &v)
void pause()
Pause for a while.
safe_init_body(internal_array_op2 init, const void *src)
Number of slots for segment pointers inside the class.
void operator()(segment_t &s, void *begin, size_type n) const
atomic< segment_t * > my_segment
Pointer to the segments table.