1 # ifndef CPPAD_UTILITY_THREAD_ALLOC_HPP
2 # define CPPAD_UTILITY_THREAD_ALLOC_HPP
24 # pragma warning(disable:4345)
41 # define CPPAD_MAX_NUM_CAPACITY 100
47 # define CPPAD_MIN_DOUBLE_CAPACITY 16
56 # define CPPAD_TRACE_CAPACITY 0
63 # define CPPAD_TRACE_THREAD 0
100 while( capacity < std::numeric_limits<size_t>::max() / 2 )
104 capacity = 3 * ( (capacity + 1) / 2 );
164 {
static bool value =
false;
206 {
if( info != CPPAD_NULL )
221 ::operator
delete(
reinterpret_cast<void*
>(info) );
223 all_info[thread] = info;
226 else if( info == CPPAD_NULL )
231 void* v_ptr = ::operator
new(size);
234 all_info[thread] = info;
356 {
static size_t number_user = 1;
362 if( number_new != 0 )
363 number_user = number_new;
388 size_t (*thread_num_new)(
void) ,
390 {
static size_t (*thread_num_user)(void) = CPPAD_NULL;
393 { thread_num_user = thread_num_new;
397 if( thread_num_user == CPPAD_NULL )
400 size_t thread = thread_num_user();
403 "parallel_setup: thread_num() >= num_threads"
519 if( num_threads == 1 )
529 num_threads <= CPPAD_MAX_NUM_THREADS ,
530 "parallel_setup: num_threads is too large"
534 "parallel_setup: num_threads == zero"
538 "parallel_setup: num_threads != 1 and in_parallel == CPPAD_NULL"
542 "parallel_setup: num_threads != 1 and thread_num == CPPAD_NULL"
547 for(
size_t thread = 0; thread <
num_threads; thread++)
559 if( num_threads > 1 )
773 min_bytes < std::numeric_limits<size_t>::max() / 2 ,
774 "get_memory(min_bytes, cap_bytes): min_bytes is too large"
784 while( capacity_vec[c_index] < min_bytes )
788 cap_bytes = capacity_vec[c_index];
792 size_t tc_index = thread * num_cap + c_index;
797 static bool first_trace =
true;
801 cout <<
"thread_alloc: Trace for Thread = " << thread;
802 cout <<
" and capacity = " << cap_bytes << endl;
807 # ifndef CPPAD_DEBUG_AND_RELEASE
816 void* v_node = available_root->
next_;
818 if( node != CPPAD_NULL )
825 void* v_ptr =
reinterpret_cast<void*
>(node + 1);
827 # ifndef CPPAD_DEBUG_AND_RELEASE
830 inuse_root->
next_ = v_node;
836 { cout <<
"get_memory: v_ptr = " << v_ptr << endl; }
850 v_node = ::operator
new(
sizeof(
block_t) + cap_bytes);
851 node =
reinterpret_cast<block_t*
>(v_node);
853 void* v_ptr =
reinterpret_cast<void*
>(node + 1);
856 # ifndef CPPAD_DEBUG_AND_RELEASE
859 inuse_root->
next_ = v_node;
865 { cout <<
"get_memory: v_ptr = " << v_ptr << endl; }
941 size_t thread = tc_index / num_cap;
942 size_t c_index = tc_index % num_cap;
948 "Attempt to return memory for a different thread "
949 "while in parallel mode"
954 # ifndef CPPAD_DEBUG_AND_RELEASE
956 void* v_node =
reinterpret_cast<void*
>(node);
958 block_t* previous = inuse_root;
959 while( (previous->
next_ != CPPAD_NULL) & (previous->
next_ != v_node) )
963 if( previous->
next_ != v_node )
965 std::ostringstream oss;
966 oss <<
"return_memory: attempt to return memory not in use";
968 oss <<
"v_ptr = " << v_ptr << endl;
969 oss <<
"thread = " << thread << endl;
970 oss <<
"capacity = " << capacity << endl;
971 oss <<
"See CPPAD_TRACE_THREAD & CPPAD_TRACE_CAPACITY in";
972 oss << endl <<
"%# include <cppad/utility/thread_alloc.hpp>" << endl;
975 std::string msg_str = oss.str();
978 const char* msg_char_star = msg_str.c_str();
986 { std::cout <<
"return_memory: v_ptr = " << v_ptr << std::endl; }
994 { ::operator
delete(
reinterpret_cast<void*
>(node) );
1001 available_root->
next_ =
reinterpret_cast<void*
>(node);
1060 thread < CPPAD_MAX_NUM_THREADS,
1061 "Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS"
1065 "Attempt to free memory for a different thread "
1066 "while in parallel mode"
1075 for(c_index = 0; c_index < num_cap; c_index++)
1076 {
size_t capacity = capacity_vec[c_index];
1078 void* v_ptr = available_root->
next_;
1079 while( v_ptr != CPPAD_NULL )
1081 void* next = node->
next_;
1082 ::operator
delete(v_ptr);
1087 available_root->
next_ = CPPAD_NULL;
1090 if(
inuse(thread) == 0 )
1354 template <
class Type>
1357 size_t min_bytes = size_min *
sizeof(Type);
1360 void* v_ptr =
get_memory(min_bytes, num_bytes);
1362 Type* array =
reinterpret_cast<Type*
>(v_ptr);
1364 size_out = num_bytes /
sizeof(Type);
1371 for(i = 0; i < size_out; i++)
1372 new(array + i) Type();
1442 template <
class Type>
1446 size_t size = node->
extra_;
1450 for(i = 0; i < size; i++)
1451 (array + i)->~Type();
1504 "free_all cannot be used while in parallel execution"
1507 size_t thread = CPPAD_MAX_NUM_THREADS;
1509 { ok &=
inuse(thread) == 0;
1520 # undef CPPAD_MAX_NUM_CAPACITY
1521 # undef CPPAD_MIN_DOUBLE_CAPACITY
1522 # undef CPPAD_TRACE_CAPACITY
1523 # undef CPPAD_TRACE_THREAD
size_t extra_
extra information (currently used by create and delete array)
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Define processor symbols and macros that are used by CppAD.
static size_t set_get_num_threads(size_t number_new)
Set and get the number of threads that are sharing memory.
void * next_
pointer to the next memory allocation with the same tc_index_
static void return_memory(void *v_ptr)
Return memory that was obtained by get_memory.
static size_t available(size_t thread)
Determine the amount of memory that is currently available for use.
block_t root_available_[100]
root of available list for this thread and each capacity
static void dec_inuse(size_t dec, size_t thread)
Decrease the number of bytes of memory that are currently in use; i.e., that been obtained with get_m...
static bool in_parallel(void)
Are we in a parallel execution state; i.e., is it possible that other threads are currently executing...
static size_t inuse(size_t thread)
Determine the amount of memory that is currently inuse.
static bool set_get_in_parallel(bool(*in_parallel_new)(void), bool set=false)
Set and call the routine that determine if we are in parallel execution mode.
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
block_t(void)
make default constructor private. It is only used by constructor for `root arrays below...
Capacity vector for memory allocation block sizes.
static const capacity_t * capacity_info(void)
Vector of fixed capacity values for this allocator.
#define CPPAD_MIN_DOUBLE_CAPACITY
Minimum number of double values that will fit in an allocation.
static size_t thread_num(void)
Get current thread number.
#define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
static void free_available(size_t thread)
Return all the memory being held as available for a thread to the system.
static size_t num_threads(void)
Get the current number of threads that thread_alloc can use.
static void dec_available(size_t dec, size_t thread)
Decrease the number of bytes of memory that are currently avaialble; i.e., have been obtained obtaine...
block_t root_inuse_[100]
root of inuse list for this thread and each capacity If NDEBUG or CPPAD_DEBUG_AND_RELEASE is defined...
size_t count_inuse_
count of available bytes for this thread
static void * get_memory(size_t min_bytes, size_t &cap_bytes)
Use thread_alloc to get a specified amount of memory.
#define CPPAD_TRACE_THREAD
If NDEBUG is not defined, print all calls to get_memory and return_memory that correspond to this the...
static size_t set_get_thread_num(size_t(*thread_num_new)(void), bool set=false)
Set and call the routine that determine the current thread number.
size_t value[100]
the different capacity values
static void hold_memory(bool value)
Change the thread_alloc hold memory setting.
static void delete_array(Type *array)
Return Memory Used for an Array to the Available Pool (include destructor call for each element)...
File used to set and get user in_parallel routine.
Structure of information for each thread.
#define CPPAD_MAX_NUM_CAPACITY
Maximum number of different capacities the allocator will attempt.
#define CPPAD_TRACE_CAPACITY
If NDEBUG is not defined, print all calls to get_memory and return_memory that correspond to this cap...
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
size_t tc_index_
an index that uniquely idenfifies both thread and capacity
static void inc_available(size_t inc, size_t thread)
Increase the number of bytes of memory that are currently avaialble; i.e., have been obtained obtaine...
static bool set_get_hold_memory(bool set, bool new_value=false)
Set and Get hold available memory flag.
size_t count_available_
count of inuse bytes for this thread
static bool free_all(void)
Return to the system all thread_alloc memory that is not currently inuse.
size_t number
number of capacity values actually used
static thread_alloc_info * thread_info(size_t thread, bool clear=false)
Get pointer to the information for this thread.
static void parallel_setup(size_t num_threads, bool(*in_parallel)(void), size_t(*thread_num)(void))
Set thread_alloc up for parallel mode usage.
static void inc_inuse(size_t inc, size_t thread)
Increase the number of bytes of memory that are currently in use; i.e., that been obtained with get_m...
static Type * create_array(size_t size_min, size_t &size_out)
Use thread_alloc to allocate an array, then call default construtor for each element.