CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
thread_alloc.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_UTILITY_THREAD_ALLOC_HPP
2 # define CPPAD_UTILITY_THREAD_ALLOC_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 # include <sstream>
16 # include <limits>
17 # include <memory>
18 
19 
20 # ifdef _MSC_VER
21 // Supress warning that Microsoft compiler changed its behavior and is now
22 // doing the correct thing at the statement:
23 // new(array + i) Type();
24 # pragma warning(disable:4345)
25 # endif
26 
28 # include <cppad/core/define.hpp>
30 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
31 /*!
32 \file thread_alloc.hpp
33 File used to define the CppAD multi-threading allocator class
34 */
35 
36 /*!
37 \def CPPAD_MAX_NUM_CAPACITY
38 Maximum number of different capacities the allocator will attempt.
39 This must be larger than the log base two of numeric_limit<size_t>::max().
40 */
41 # define CPPAD_MAX_NUM_CAPACITY 100
42 
43 /*!
44 \def CPPAD_MIN_DOUBLE_CAPACITY
45 Minimum number of double values that will fit in an allocation.
46 */
47 # define CPPAD_MIN_DOUBLE_CAPACITY 16
48 
49 /*!
50 \def CPPAD_TRACE_CAPACITY
51 If NDEBUG is not defined, print all calls to \c get_memory and \c return_memory
52 that correspond to this capacity and thread CPPAD_TRACE_THREAD.
53 (Note that if CPPAD_TRACE_CAPACITY is zero, or any other value not in the list
54 of capacities, no tracing will be done.)
55 */
56 # define CPPAD_TRACE_CAPACITY 0
57 
58 /*!
59 \def CPPAD_TRACE_THREAD
60 If NDEBUG is not defined, print all calls to \c get_memory and \c return_memory
61 that correspond to this thead and capacity CPPAD_TRACE_CAPACITY.
62 */
63 # define CPPAD_TRACE_THREAD 0
64 
65 /*
66 Note that Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for
67 objects with static storage duration (3.7.1) shall be zero-initialized
68 (8.5) before any other initialization takes place."
69 */
70 
71 /*!
72 Capacity vector for memory allocation block sizes.
73 
74 Only one of these objects should be created and used as a
75 static variable inside of the \c thread_alloc::capacity_info function.
76 */
77 
78 /*!
79 Allocator class that works well with an multi-threading environment.
80 */
82 // ============================================================================
83 private:
84 
85  class capacity_t {
86  public:
87  /// number of capacity values actually used
88  size_t number;
89  /// the different capacity values
91  /// ctor
92  capacity_t(void)
93  { // Cannot figure out how to call thread_alloc::in_parallel here.
94  // CPPAD_ASSERT_UNKNOWN(
95  // ! thread_alloc::in_parallel() , "thread_alloc: "
96  // "parallel mode and parallel_setup not yet called."
97  // );
98  number = 0;
99  size_t capacity = CPPAD_MIN_DOUBLE_CAPACITY * sizeof(double);
100  while( capacity < std::numeric_limits<size_t>::max() / 2 )
102  value[number++] = capacity;
103  // next capactiy is 3/2 times the current one
104  capacity = 3 * ( (capacity + 1) / 2 );
105  }
107  }
108  };
109 
110  class block_t {
111  public:
112  /// extra information (currently used by create and delete array)
113  size_t extra_;
114  /// an index that uniquely idenfifies both thread and capacity
115  size_t tc_index_;
116  /// pointer to the next memory allocation with the same tc_index_
117  void* next_;
118  // -----------------------------------------------------------------
119  /// make default constructor private. It is only used by constructor
120  /// for `root arrays below.
121  block_t(void) : extra_(0), tc_index_(0), next_(CPPAD_NULL)
122  { }
123  };
124 
125  // ---------------------------------------------------------------------
126  /// Vector of fixed capacity values for this allocator
127  static const capacity_t* capacity_info(void)
129  static const capacity_t capacity;
130  return &capacity;
131  }
132  // ---------------------------------------------------------------------
133  /// Structure of information for each thread
135  /// count of available bytes for this thread
136  size_t count_inuse_;
137  /// count of inuse bytes for this thread
139  /// root of available list for this thread and each capacity
141  /*!
142  root of inuse list for this thread and each capacity
143  If NDEBUG or CPPAD_DEBUG_AND_RELEASE is defined, this memory is not
144  used, but it still helps to separate this structure from the structure
145  for the next thread.
146  */
148  };
149  // ---------------------------------------------------------------------
150  /*!
151  Set and Get hold available memory flag.
152 
153  \param set [in]
154  if true, the value returned by this return is changed.
155 
156  \param new_value [in]
157  if \a set is true, this is the new value returned by this routine.
158  Otherwise, \c new_value is ignored.
159 
160  \return
161  the current setting for this routine (which is initially false).
162  */
163  static bool set_get_hold_memory(bool set, bool new_value = false)
164  { static bool value = false;
165  if( set )
166  value = new_value;
167  return value;
168  }
169  // ---------------------------------------------------------------------
170  /*!
171  Get pointer to the information for this thread.
172 
173  \param thread [in]
174  Is the thread number for this information pointer.
175 
176  \param clear
177  If \a clear is true, then the information pointer for this thread
178  is deleted and the \c CPPAD_NULL pointer is returned.
179  There must be no memory currently in either the inuse or avaialble
180  lists when this routine is called.
181 
182  \return
183  is the current informaiton pointer for this thread.
184  If \a clear is false, and the current pointer is CPPAD_NULL,
185  a new infromation record is allocated and its pointer returned.
186  In this case, if \c info is the retured pointer,
187  <code>info->count_inuse == 0</code> and
188  <code>info->count_available == 0</code>.
189  In addition,
190  for <code>c = 0 , ... , CPPAD_MAX_NUM_CAPACITY-1</code>
191  <code>info->root_inuse_[c].next_ == CPPAD_NULL</code> and
192  <code>info->root_available_[c].next_ == CPPAD_NULL</code>.
193  */
195  size_t thread ,
196  bool clear = false )
197  { static thread_alloc_info* all_info[CPPAD_MAX_NUM_THREADS];
198  static thread_alloc_info zero_info;
199 
201 
202  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );
203 
204  thread_alloc_info* info = all_info[thread];
205  if( clear )
206  { if( info != CPPAD_NULL )
207  {
208 # ifndef NDEBUG
210  info->count_inuse_ == 0 &&
211  info->count_available_ == 0
212  );
213  for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)
215  info->root_inuse_[c].next_ == CPPAD_NULL &&
216  info->root_available_[c].next_ == CPPAD_NULL
217  );
218  }
219 # endif
220  if( thread != 0 )
221  ::operator delete( reinterpret_cast<void*>(info) );
222  info = CPPAD_NULL;
223  all_info[thread] = info;
224  }
225  }
226  else if( info == CPPAD_NULL )
227  { if( thread == 0 )
228  info = &zero_info;
229  else
230  { size_t size = sizeof(thread_alloc_info);
231  void* v_ptr = ::operator new(size);
232  info = reinterpret_cast<thread_alloc_info*>(v_ptr);
233  }
234  all_info[thread] = info;
235 
236  // initialize the information record
237  for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)
238  { info->root_inuse_[c].next_ = CPPAD_NULL;
239  info->root_available_[c].next_ = CPPAD_NULL;
240  }
241  info->count_inuse_ = 0;
242  info->count_available_ = 0;
243  }
244  return info;
245  }
246  // -----------------------------------------------------------------------
247  /*!
248  Increase the number of bytes of memory that are currently in use; i.e.,
249  that been obtained with \c get_memory and not yet returned.
250 
251  \param inc [in]
252  amount to increase memory in use.
253 
254  \param thread [in]
255  Thread for which we are increasing the number of bytes in use
256  (must be less than \c num_threads).
257  Durring parallel execution, this must be the thread
258  that is currently executing.
259  */
260  static void inc_inuse(size_t inc, size_t thread)
261  {
262  CPPAD_ASSERT_UNKNOWN( thread < num_threads() );
264  thread == thread_num() || (! in_parallel())
265  );
266  thread_alloc_info* info = thread_info(thread);
267 
268  // do the addition
269  size_t result = info->count_inuse_ + inc;
270  CPPAD_ASSERT_UNKNOWN( result >= info->count_inuse_ );
271 
272  info->count_inuse_ = result;
273  }
274  // -----------------------------------------------------------------------
275  /*!
276  Increase the number of bytes of memory that are currently avaialble; i.e.,
277  have been obtained obtained from the system and are being held future use.
278 
279  \copydetails inc_inuse
280  */
281  static void inc_available(size_t inc, size_t thread)
282  {
283  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
285  thread == thread_num() || (! in_parallel())
286  );
287  thread_alloc_info* info = thread_info(thread);
288  // do the addition
289  size_t result = info->count_available_ + inc;
290  CPPAD_ASSERT_UNKNOWN( result >= info->count_available_ );
291 
292  info->count_available_ = result;
293  }
294  // -----------------------------------------------------------------------
295  /*!
296  Decrease the number of bytes of memory that are currently in use; i.e.,
297  that been obtained with \c get_memory and not yet returned.
298 
299  \param dec [in]
300  amount to decrease number of bytes in use.
301 
302  \param thread [in]
303  Thread for which we are decreasing the number of bytes in use
304  (must be less than \c num_threads).
305  Durring parallel execution, this must be the thread
306  that is currently executing.
307  */
308  static void dec_inuse(size_t dec, size_t thread)
309  {
311  thread < num_threads() || (! in_parallel())
312  );
314  thread == thread_num() || (! in_parallel())
315  );
316  thread_alloc_info* info = thread_info(thread);
317 
318  // do the subtraction
319  CPPAD_ASSERT_UNKNOWN( info->count_inuse_ >= dec );
320  info->count_inuse_ = info->count_inuse_ - dec;
321  }
322  // -----------------------------------------------------------------------
323  /*!
324  Decrease the number of bytes of memory that are currently avaialble; i.e.,
325  have been obtained obtained from the system and are being held future use.
326 
327  \copydetails dec_inuse
328  */
329  static void dec_available(size_t dec, size_t thread)
330  {
331  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
333  thread == thread_num() || (! in_parallel())
334  );
335  thread_alloc_info* info = thread_info(thread);
336  // do the subtraction
337  CPPAD_ASSERT_UNKNOWN( info->count_available_ >= dec );
338  info->count_available_ = info->count_available_ - dec;
339  }
340 
341  // ----------------------------------------------------------------------
342  /*!
343  Set and get the number of threads that are sharing memory.
344 
345  \param number_new
346  If \c number is zero, we are only retreiving the current maximum
347  number of threads. Otherwise, we are setting and retreiving
348  maximum number of threads.
349 
350  \return
351  the number of threads that are sharing memory.
352  If \c number_new is non-zero, the return value is equal to
353  \c number_new.
354  */
355  static size_t set_get_num_threads(size_t number_new)
356  { static size_t number_user = 1;
357 
358  CPPAD_ASSERT_UNKNOWN( number_new <= CPPAD_MAX_NUM_THREADS );
359  CPPAD_ASSERT_UNKNOWN( ! in_parallel() || (number_new == 0) );
360 
361  // case where we are changing the number of threads
362  if( number_new != 0 )
363  number_user = number_new;
364 
365  return number_user;
366  }
367  /*!
368  Set and call the routine that determine the current thread number.
369 
370  \return
371  returns value for the most recent setting for \a thread_num_new.
372  If \a set is true,
373  or the most recent setting is \c CPPAD_NULL (its initial value),
374  the return value is zero.
375  Otherwise the routine corresponding to the most recent setting
376  is called and its value returned by \c set_get_thread_num.
377 
378  \param thread_num_new [in]
379  If \a set is false, \a thread_num_new it is not used.
380  Otherwise, the current value of \c thread_num_new becomes the
381  most recent setting for thread_num.
382 
383  \param set
384  If \a set is true, then \a thread_num_new is becomes the most
385  recent setting for this \c set_get_thread_num.
386  */
387  static size_t set_get_thread_num(
388  size_t (*thread_num_new)(void) ,
389  bool set = false )
390  { static size_t (*thread_num_user)(void) = CPPAD_NULL;
391 
392  if( set )
393  { thread_num_user = thread_num_new;
394  return 0;
395  }
396 
397  if( thread_num_user == CPPAD_NULL )
398  return 0;
399 
400  size_t thread = thread_num_user();
402  thread < set_get_num_threads(0) ,
403  "parallel_setup: thread_num() >= num_threads"
404  );
405  return thread;
406  }
407 // ============================================================================
408 public:
409 /*
410 $begin ta_parallel_setup$$
411 $spell
412  alloc
413  num
414  bool
415 $$
416 $section Setup thread_alloc For Use in Multi-Threading Environment$$
417 $mindex parallel initialize$$
418 
419 
420 
421 
422 $head Syntax$$
423 $codei%thread_alloc::parallel_setup(%num_threads%, %in_parallel%, %thread_num%)
424 %$$
425 
426 $head Purpose$$
427 By default there is only one thread and all execution is in sequential mode,
428 i.e., multiple threads are not sharing the same memory; i.e.
429 not in parallel mode.
430 
431 $head Speed$$
432 It should be faster, even when $icode num_thread$$ is equal to one,
433 for $code thread_alloc$$ to hold onto memory.
434 This can be accomplished using the function call
435 $codei%
436  thread_alloc::hold_memory(true)
437 %$$
438 see $cref/hold_memory/ta_hold_memory/$$.
439 
440 $head num_threads$$
441 This argument has prototype
442 $codei%
443  size_t %num_threads%
444 %$$
445 and must be greater than zero.
446 It specifies the number of threads that are sharing memory.
447 The case $icode%num_threads% == 1%$$ is a special case that is
448 used to terminate a multi-threading environment.
449 
450 $head in_parallel$$
451 This function has prototype
452 $codei%
453  bool %in_parallel%(void)
454 %$$
455 It must return $code true$$ if there is more than one thread
456 currently executing.
457 Otherwise it can return false.
458 $pre
459 
460 $$
461 In the special case where $icode%num_threads% == 1%$$,
462 the routine $icode in_parallel$$ is not used.
463 
464 $head thread_num$$
465 This function has prototype
466 $codei%
467  size_t %thread_num%(void)
468 %$$
469 It must return a thread number that uniquely identifies the
470 currently executing thread.
471 Furthermore
472 $codei%
473  0 <= %thread_num%() < %num_threads%
474 %$$.
475 In the special case where $icode%num_threads% == 1%$$,
476 the routine $icode thread_num$$ is not used.
477 $pre
478 
479 $$
480 Note that this function is called by other routines so,
481 as soon as a new thread is executing,
482 one must be certain that $icode thread_num()$$ will
483 work for that thread.
484 
485 $head Restrictions$$
486 The function $code parallel_setup$$ must be called before
487 the program enters $cref/parallel/ta_in_parallel/$$ execution mode.
488 In addition, this function cannot be called while in parallel mode.
489 
490 $head Example$$
491 The files
492 $cref simple_ad_openmp.cpp$$,
493 $cref simple_ad_bthread.cpp$$, and
494 $cref simple_ad_pthread.cpp$$,
495 contain examples and tests that use this function.
496 
497 $end
498 */
499  /*!
500  Set thread_alloc up for parallel mode usage.
501 
502  \param num_threads [in]
503  Is the number of thread that may be executing at the same time.
504 
505  \param in_parallel [in]
506  Is the routine that determines if we are in parallel mode or not.
507 
508  \param thread_num [in]
509  Is the routine that determines the current thread number
510  (between zero and num_threads minus one).
511  */
512  static void parallel_setup(
513  size_t num_threads ,
514  bool (*in_parallel)(void) ,
515  size_t (*thread_num)(void) )
516  {
517  // Special case where we go back to single thread mode right away
518  // (previous settings may no longer be valid)
519  if( num_threads == 1 )
520  { bool set = true;
521  set_get_num_threads(num_threads);
522  // emphasize that this routine is outside thread_alloc class
523  CppAD::local::set_get_in_parallel(CPPAD_NULL, set);
524  set_get_thread_num(CPPAD_NULL, set);
525  return;
526  }
527 
529  num_threads <= CPPAD_MAX_NUM_THREADS ,
530  "parallel_setup: num_threads is too large"
531  );
533  num_threads != 0 ,
534  "parallel_setup: num_threads == zero"
535  );
537  in_parallel != CPPAD_NULL ,
538  "parallel_setup: num_threads != 1 and in_parallel == CPPAD_NULL"
539  );
541  thread_num != CPPAD_NULL ,
542  "parallel_setup: num_threads != 1 and thread_num == CPPAD_NULL"
543  );
544 
545  // Make sure that constructors for all static variables in this file
546  // are called in sequential mode.
547  for(size_t thread = 0; thread < num_threads; thread++)
548  thread_info(thread);
549  capacity_info();
550  size_t cap_bytes;
551  void* v_ptr = get_memory(0, cap_bytes);
552 
553  // free memory allocated by call to get_memory above
554  return_memory(v_ptr);
555  free_available( set_get_thread_num(CPPAD_NULL) );
556 
557  // delay this so thread_num() call above is in previous mode
558  // (current setings may not yet be valid)
559  if( num_threads > 1 )
560  { bool set = true;
561  set_get_num_threads(num_threads);
562  // emphasize that this routine is outside thread_alloc class
565  }
566  }
567 /*
568 $begin ta_num_threads$$
569 $spell
570  inv
571  CppAD
572  num
573  alloc
574 $$
575 $section Get Number of Threads$$
576 
577 
578 $head Syntax$$
579 $icode%number% = thread_alloc::num_threads()%$$
580 
581 $head Purpose$$
582 Determine the number of threads as set during $cref/parallel_setup/ta_parallel_setup/$$.
583 
584 $head number$$
585 The return value $icode number$$ has prototype
586 $codei%
587  size_t %number%
588 %$$
589 and is equal to the value of
590 $cref/num_threads/ta_parallel_setup/num_threads/$$
591 in the previous call to $icode parallel_setup$$.
592 If there was no such previous call, the value one is returned.
593 
594 $head Example$$
595 The example and test $cref thread_alloc.cpp$$ uses this routine.
596 
597 $end
598 */
599  /*!
600  Get the current number of threads that thread_alloc can use.
601  */
602  static size_t num_threads(void)
603  { return set_get_num_threads(0); }
604 /* -----------------------------------------------------------------------
605 $begin ta_in_parallel$$
606 
607 $section Is The Current Execution in Parallel Mode$$
608 $mindex sequential$$
609 $spell
610  thread_alloc
611  bool
612 $$
613 
614 
615 $head Syntax$$
616 $icode%flag% = thread_alloc::in_parallel()%$$
617 
618 $head Purpose$$
619 Some of the $cref thread_alloc$$ allocation routines have different
620 specifications for parallel (not sequential) execution mode.
621 This routine enables you to determine if the current execution mode
622 is sequential or parallel.
623 
624 $head flag$$
625 The return value has prototype
626 $codei%
627  bool %flag%
628 %$$
629 It is true if the current execution is in parallel mode
630 (possibly multi-threaded) and false otherwise (sequential mode).
631 
632 $head Example$$
633 $cref thread_alloc.cpp$$
634 
635 $end
636 */
637  /// Are we in a parallel execution state; i.e., is it possible that
638  /// other threads are currently executing.
639  static bool in_parallel(void)
640  { // emphasize that this routine is outside thread_alloc class
642  }
643 /* -----------------------------------------------------------------------
644 $begin ta_thread_num$$
645 $spell
646  CppAD
647  num
648  thread_alloc
649  cppad.hpp
650 $$
651 
652 $section Get the Current Thread Number$$
653 
654 
655 $head Syntax$$
656 $icode%thread% = thread_alloc::thread_num()%$$
657 
658 $head Purpose$$
659 Some of the $cref thread_alloc$$ allocation routines have a thread number.
660 This routine enables you to determine the current thread.
661 
662 $head thread$$
663 The return value $icode thread$$ has prototype
664 $codei%
665  size_t %thread%
666 %$$
667 and is the currently executing thread number.
668 
669 $head Example$$
670 $cref thread_alloc.cpp$$
671 
672 $end
673 */
674  /// Get current thread number
675  static size_t thread_num(void)
676  { return set_get_thread_num(CPPAD_NULL); }
677 /* -----------------------------------------------------------------------
678 $begin ta_get_memory$$
679 $spell
680  std
681  num
682  ptr
683  thread_alloc
684 $$
685 
686 $section Get At Least A Specified Amount of Memory$$
687 $mindex allocate$$
688 
689 
690 $head Syntax$$
691 $icode%v_ptr% = thread_alloc::get_memory(%min_bytes%, %cap_bytes%)%$$
692 
693 $head Purpose$$
694 Use $cref thread_alloc$$ to obtain a minimum number of bytes of memory
695 (for use by the $cref/current thread/ta_thread_num/$$).
696 
697 $head min_bytes$$
698 This argument has prototype
699 $codei%
700  size_t %min_bytes%
701 %$$
702 It specifies the minimum number of bytes to allocate.
703 This value must be less than
704 $codep
705  std::numeric_limits<size_t>::max() / 2
706 $$
707 
708 $head cap_bytes$$
709 This argument has prototype
710 $codei%
711  size_t& %cap_bytes%
712 %$$
713 It's input value does not matter.
714 Upon return, it is the actual number of bytes (capacity)
715 that have been allocated for use,
716 $codei%
717  %min_bytes% <= %cap_bytes%
718 %$$
719 
720 $head v_ptr$$
721 The return value $icode v_ptr$$ has prototype
722 $codei%
723  void* %v_ptr%
724 %$$
725 It is the location where the $icode cap_bytes$$ of memory
726 that have been allocated for use begins.
727 
728 $head Allocation Speed$$
729 This allocation should be faster if the following conditions hold:
730 $list number$$
731 The memory allocated by a previous call to $code get_memory$$
732 is currently available for use.
733 $lnext
734 The current $icode min_bytes$$ is between
735 the previous $icode min_bytes$$ and previous $icode cap_bytes$$.
736 $lend
737 
738 $head Alignment$$
739 We call a memory allocation aligned if the address is a multiple
740 of the number of bytes in a $code size_t$$ value.
741 If the system $code new$$ allocator is aligned, then $icode v_ptr$$
742 pointer is also aligned.
743 
744 $head Example$$
745 $cref thread_alloc.cpp$$
746 
747 $end
748 */
749  /*!
750  Use thread_alloc to get a specified amount of memory.
751 
752  If the memory allocated by a previous call to \c get_memory is now
753  avaialable, and \c min_bytes is between its previous value
754  and the previous \c cap_bytes, this memory allocation will have
755  optimal speed. Otherwise, the memory allocation is more complicated and
756  may have to wait for other threads to complete an allocation.
757 
758  \param min_bytes [in]
759  The minimum number of bytes of memory to be obtained for use.
760 
761  \param cap_bytes [out]
762  The actual number of bytes of memory obtained for use.
763 
764  \return
765  pointer to the beginning of the memory allocated for use.
766  */
767  static void* get_memory(size_t min_bytes, size_t& cap_bytes)
768  { // see first_trace below
770 
771  // check that number of requested bytes is not to large
773  min_bytes < std::numeric_limits<size_t>::max() / 2 ,
774  "get_memory(min_bytes, cap_bytes): min_bytes is too large"
775  );
776 
777  size_t num_cap = capacity_info()->number;
778  using std::cout;
779  using std::endl;
780 
781  // determine the capacity for this request
782  size_t c_index = 0;
783  const size_t* capacity_vec = capacity_info()->value;
784  while( capacity_vec[c_index] < min_bytes )
785  { ++c_index;
786  CPPAD_ASSERT_UNKNOWN(c_index < num_cap );
787  }
788  cap_bytes = capacity_vec[c_index];
789 
790  // determine the thread, capacity, and info for this thread
791  size_t thread = thread_num();
792  size_t tc_index = thread * num_cap + c_index;
793  thread_alloc_info* info = thread_info(thread);
794 
795 # ifndef NDEBUG
796  // trace allocation
797  static bool first_trace = true;
798  if( cap_bytes == CPPAD_TRACE_CAPACITY &&
799  thread == CPPAD_TRACE_THREAD && first_trace )
800  { cout << endl;
801  cout << "thread_alloc: Trace for Thread = " << thread;
802  cout << " and capacity = " << cap_bytes << endl;
803  if( first_trace )
804  first_trace = false;
805  }
806 
807 # ifndef CPPAD_DEBUG_AND_RELEASE
808  // Root nodes for both lists. Note these are different for different
809  // threads because tc_index is different for different threads.
810  block_t* inuse_root = info->root_inuse_ + c_index;
811 # endif
812 # endif
813  block_t* available_root = info->root_available_ + c_index;
814 
815  // check if we already have a node we can use
816  void* v_node = available_root->next_;
817  block_t* node = reinterpret_cast<block_t*>(v_node);
818  if( node != CPPAD_NULL )
819  { CPPAD_ASSERT_UNKNOWN( node->tc_index_ == tc_index );
820 
821  // remove node from available list
822  available_root->next_ = node->next_;
823 
824  // return value for get_memory
825  void* v_ptr = reinterpret_cast<void*>(node + 1);
826 # ifndef NDEBUG
827 # ifndef CPPAD_DEBUG_AND_RELEASE
828  // add node to inuse list
829  node->next_ = inuse_root->next_;
830  inuse_root->next_ = v_node;
831 # endif
832 
833  // trace allocation
834  if( cap_bytes == CPPAD_TRACE_CAPACITY &&
835  thread == CPPAD_TRACE_THREAD )
836  { cout << "get_memory: v_ptr = " << v_ptr << endl; }
837 # endif
838 
839  // adjust counts
840  inc_inuse(cap_bytes, thread);
841  dec_available(cap_bytes, thread);
842 
843  // return pointer to memory, do not inclue thread_alloc information
844  return v_ptr;
845  }
846 
847  // Create a new node with thread_alloc information at front.
848  // This uses the system allocator, which is thread safe, but slower,
849  // because the thread might wait for a lock on the allocator.
850  v_node = ::operator new(sizeof(block_t) + cap_bytes);
851  node = reinterpret_cast<block_t*>(v_node);
852  node->tc_index_ = tc_index;
853  void* v_ptr = reinterpret_cast<void*>(node + 1);
854 
855 # ifndef NDEBUG
856 # ifndef CPPAD_DEBUG_AND_RELEASE
857  // add node to inuse list
858  node->next_ = inuse_root->next_;
859  inuse_root->next_ = v_node;
860 # endif
861 
862  // trace allocation
863  if( cap_bytes == CPPAD_TRACE_CAPACITY &&
864  thread == CPPAD_TRACE_THREAD )
865  { cout << "get_memory: v_ptr = " << v_ptr << endl; }
866 # endif
867 
868  // adjust counts
869  inc_inuse(cap_bytes, thread);
870 
871  return v_ptr;
872  }
873 
874 /* -----------------------------------------------------------------------
875 $begin ta_return_memory$$
876 $spell
877  num
878  ptr
879  thread_alloc
880 $$
881 
882 $section Return Memory to thread_alloc$$
883 $mindex return_memory available$$
884 
885 
886 $head Syntax$$
887 $codei%thread_alloc::return_memory(%v_ptr%)%$$
888 
889 $head Purpose$$
890 If $cref/hold_memory/ta_hold_memory/$$ is false,
891 the memory is returned to the system.
892 Otherwise, the memory is retained by $cref thread_alloc$$ for quick future use
893 by the thread that allocated to memory.
894 
895 $head v_ptr$$
896 This argument has prototype
897 $codei%
898  void* %v_ptr%
899 %$$.
900 It must be a pointer to memory that is currently in use; i.e.
901 obtained by a previous call to
902 $cref/get_memory/ta_get_memory/$$ and not yet returned.
903 
904 $head Thread$$
905 Either the $cref/current thread/ta_thread_num/$$ must be the same as during
906 the corresponding call to $cref/get_memory/ta_get_memory/$$,
907 or the current execution mode must be sequential
908 (not $cref/parallel/ta_in_parallel/$$).
909 
910 $head NDEBUG$$
911 If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster).
912 Otherwise, a list of in use pointers is searched to make sure
913 that $icode v_ptr$$ is in the list.
914 
915 $head Example$$
916 $cref thread_alloc.cpp$$
917 
918 $end
919 */
920  /*!
921  Return memory that was obtained by \c get_memory.
922  If <code>num_threads() == 1</code>,
923  the memory is returned to the system.
924  Otherwise, it is retained by \c thread_alloc and available for use by
925  \c get_memory for this thread.
926 
927  \param v_ptr [in]
928  Value of the pointer returned by \c get_memory and still in use.
929  After this call, this pointer will available (and not in use).
930 
931  \par
932  We must either be in sequential (not parallel) execution mode,
933  or the current thread must be the same as for the corresponding call
934  to \c get_memory.
935  */
936  static void return_memory(void* v_ptr)
937  { size_t num_cap = capacity_info()->number;
938 
939  block_t* node = reinterpret_cast<block_t*>(v_ptr) - 1;
940  size_t tc_index = node->tc_index_;
941  size_t thread = tc_index / num_cap;
942  size_t c_index = tc_index % num_cap;
943  size_t capacity = capacity_info()->value[c_index];
944 
945  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );
947  thread == thread_num() || (! in_parallel()),
948  "Attempt to return memory for a different thread "
949  "while in parallel mode"
950  );
951 
952  thread_alloc_info* info = thread_info(thread);
953 # ifndef NDEBUG
954 # ifndef CPPAD_DEBUG_AND_RELEASE
955  // remove node from inuse list
956  void* v_node = reinterpret_cast<void*>(node);
957  block_t* inuse_root = info->root_inuse_ + c_index;
958  block_t* previous = inuse_root;
959  while( (previous->next_ != CPPAD_NULL) & (previous->next_ != v_node) )
960  previous = reinterpret_cast<block_t*>(previous->next_);
961 
962  // check that v_ptr is valid
963  if( previous->next_ != v_node )
964  { using std::endl;
965  std::ostringstream oss;
966  oss << "return_memory: attempt to return memory not in use";
967  oss << endl;
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;
973  // oss.str() returns a string object with a copy of the current
974  // contents in the stream buffer.
975  std::string msg_str = oss.str();
976  // msg_str.c_str() returns a pointer to the c-string
977  // representation of the string object's value.
978  const char* msg_char_star = msg_str.c_str();
979  CPPAD_ASSERT_KNOWN(false, msg_char_star );
980  }
981  // remove v_ptr from inuse list
982  previous->next_ = node->next_;
983 # endif
984  // trace option
985  if( capacity==CPPAD_TRACE_CAPACITY && thread==CPPAD_TRACE_THREAD )
986  { std::cout << "return_memory: v_ptr = " << v_ptr << std::endl; }
987 
988 # endif
989  // capacity bytes are removed from the inuse pool
990  dec_inuse(capacity, thread);
991 
992  // check for case where we just return the memory to the system
993  if( ! set_get_hold_memory(false) )
994  { ::operator delete( reinterpret_cast<void*>(node) );
995  return;
996  }
997 
998  // add this node to available list for this thread and capacity
999  block_t* available_root = info->root_available_ + c_index;
1000  node->next_ = available_root->next_;
1001  available_root->next_ = reinterpret_cast<void*>(node);
1002 
1003  // capacity bytes are added to the available pool
1004  inc_available(capacity, thread);
1005  }
1006 /* -----------------------------------------------------------------------
1007 $begin ta_free_available$$
1008 $spell
1009  num
1010  thread_alloc
1011 $$
1012 
1013 $section Free Memory Currently Available for Quick Use by a Thread$$
1014 $mindex free_available$$
1015 $spell
1016  inuse
1017 $$
1018 
1019 
1020 $head Syntax$$
1021 $codei%thread_alloc::free_available(%thread%)%$$
1022 
1023 $head Purpose$$
1024 Return to the system all the memory that is currently being
1025 $cref/held/ta_hold_memory/$$ for quick use by the specified thread.
1026 
1027 $subhead Extra Memory$$
1028 In the case where $icode%thread% > 0%$$,
1029 some extra memory is used to track allocations by the specified thread.
1030 If
1031 $codei%
1032  thread_alloc::inuse(%thread%) == 0
1033 %$$
1034 the extra memory is also returned to the system.
1035 
1036 $head thread$$
1037 This argument has prototype
1038 $codei%
1039  size_t %thread%
1040 %$$
1041 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
1042 or the current execution mode must be sequential
1043 (not $cref/parallel/ta_in_parallel/$$).
1044 
1045 $head Example$$
1046 $cref thread_alloc.cpp$$
1047 
1048 $end
1049 */
1050  /*!
1051  Return all the memory being held as available for a thread to the system.
1052 
1053  \param thread [in]
1054  this thread that will no longer have any available memory after this call.
1055  This must either be the thread currently executing, or we must be
1056  in sequential (not parallel) execution mode.
1057  */
1058  static void free_available(size_t thread)
1060  thread < CPPAD_MAX_NUM_THREADS,
1061  "Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS"
1062  );
1064  thread == thread_num() || (! in_parallel()),
1065  "Attempt to free memory for a different thread "
1066  "while in parallel mode"
1067  );
1068 
1069  size_t num_cap = capacity_info()->number;
1070  if( num_cap == 0 )
1071  return;
1072  const size_t* capacity_vec = capacity_info()->value;
1073  size_t c_index;
1074  thread_alloc_info* info = thread_info(thread);
1075  for(c_index = 0; c_index < num_cap; c_index++)
1076  { size_t capacity = capacity_vec[c_index];
1077  block_t* available_root = info->root_available_ + c_index;
1078  void* v_ptr = available_root->next_;
1079  while( v_ptr != CPPAD_NULL )
1080  { block_t* node = reinterpret_cast<block_t*>(v_ptr);
1081  void* next = node->next_;
1082  ::operator delete(v_ptr);
1083  v_ptr = next;
1084 
1085  dec_available(capacity, thread);
1086  }
1087  available_root->next_ = CPPAD_NULL;
1088  }
1089  CPPAD_ASSERT_UNKNOWN( available(thread) == 0 );
1090  if( inuse(thread) == 0 )
1091  { // clear the information for this thread
1092  thread_info(thread, true);
1093  }
1094  }
1095 /* -----------------------------------------------------------------------
1096 $begin ta_hold_memory$$
1097 $spell
1098  alloc
1099  num
1100 $$
1101 
1102 $section Control When Thread Alloc Retains Memory For Future Use$$
1103 $mindex hold$$
1104 
1105 $head Syntax$$
1106 $codei%thread_alloc::hold_memory(%value%)%$$
1107 
1108 $head Purpose$$
1109 It should be faster, even when $icode num_thread$$ is equal to one,
1110 for $code thread_alloc$$ to hold onto memory.
1111 Calling $icode hold_memory$$ with $icode value$$ equal to true,
1112 instructs $code thread_alloc$$ to hold onto memory,
1113 and put it in the $cref/available/ta_available/$$ pool,
1114 after each call to $cref/return_memory/ta_return_memory/$$.
1115 
1116 $head value$$
1117 If $icode value$$ is true,
1118 $code thread_alloc$$ with hold onto memory for future quick use.
1119 If it is false, future calls to $cref/return_memory/ta_return_memory/$$
1120 will return the corresponding memory to the system.
1121 By default (when $code hold_memory$$ has not been called)
1122 $code thread_alloc$$ does not hold onto memory.
1123 
1124 $head free_available$$
1125 Memory that is being held by $code thread_alloc$$ can be returned
1126 to the system using $cref/free_available/ta_free_available/$$.
1127 
1128 $end
1129 */
1130  /*!
1131  Change the thread_alloc hold memory setting.
1132 
1133  \param value [in]
1134  New value for the thread_alloc hold memory setting.
1135  */
1136  static void hold_memory(bool value)
1137  { bool set = true;
1138  set_get_hold_memory(set, value);
1139  }
1140 
1141 /* -----------------------------------------------------------------------
1142 $begin ta_inuse$$
1143 $spell
1144  num
1145  inuse
1146  thread_alloc
1147 $$
1148 
1149 $section Amount of Memory a Thread is Currently Using$$
1150 $mindex inuse$$
1151 
1152 
1153 $head Syntax$$
1154 $icode%num_bytes% = thread_alloc::inuse(%thread%)%$$
1155 
1156 $head Purpose$$
1157 Memory being managed by $cref thread_alloc$$ has two states,
1158 currently in use by the specified thread,
1159 and quickly available for future use by the specified thread.
1160 This function informs the program how much memory is in use.
1161 
1162 $head thread$$
1163 This argument has prototype
1164 $codei%
1165  size_t %thread%
1166 %$$
1167 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
1168 or the current execution mode must be sequential
1169 (not $cref/parallel/ta_in_parallel/$$).
1170 
1171 $head num_bytes$$
1172 The return value has prototype
1173 $codei%
1174  size_t %num_bytes%
1175 %$$
1176 It is the number of bytes currently in use by the specified thread.
1177 
1178 $head Example$$
1179 $cref thread_alloc.cpp$$
1180 
1181 $end
1182 */
1183  /*!
1184  Determine the amount of memory that is currently inuse.
1185 
1186  \param thread [in]
1187  Thread for which we are determining the amount of memory
1188  (must be < CPPAD_MAX_NUM_THREADS).
1189  Durring parallel execution, this must be the thread
1190  that is currently executing.
1191 
1192  \return
1193  The amount of memory in bytes.
1194  */
1195  static size_t inuse(size_t thread)
1196  {
1197  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
1199  thread == thread_num() || (! in_parallel())
1200  );
1201  thread_alloc_info* info = thread_info(thread);
1202  return info->count_inuse_;
1203  }
1204 /* -----------------------------------------------------------------------
1205 $begin ta_available$$
1206 $spell
1207  num
1208  thread_alloc
1209 $$
1210 
1211 $section Amount of Memory Available for Quick Use by a Thread$$
1212 
1213 
1214 $head Syntax$$
1215 $icode%num_bytes% = thread_alloc::available(%thread%)%$$
1216 
1217 $head Purpose$$
1218 Memory being managed by $cref thread_alloc$$ has two states,
1219 currently in use by the specified thread,
1220 and quickly available for future use by the specified thread.
1221 This function informs the program how much memory is available.
1222 
1223 $head thread$$
1224 This argument has prototype
1225 $codei%
1226  size_t %thread%
1227 %$$
1228 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
1229 or the current execution mode must be sequential
1230 (not $cref/parallel/ta_in_parallel/$$).
1231 
1232 $head num_bytes$$
1233 The return value has prototype
1234 $codei%
1235  size_t %num_bytes%
1236 %$$
1237 It is the number of bytes currently available for use by the specified thread.
1238 
1239 $head Example$$
1240 $cref thread_alloc.cpp$$
1241 
1242 $end
1243 */
1244  /*!
1245  Determine the amount of memory that is currently available for use.
1246 
1247  \copydetails inuse
1248  */
1249  static size_t available(size_t thread)
1250  {
1251  CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
1253  thread == thread_num() || (! in_parallel())
1254  );
1255  thread_alloc_info* info = thread_info(thread);
1256  return info->count_available_;
1257  }
1258 /* -----------------------------------------------------------------------
1259 $begin ta_create_array$$
1260 $spell
1261  inuse
1262  thread_alloc
1263  sizeof
1264 $$
1265 
1266 $section Allocate An Array and Call Default Constructor for its Elements$$
1267 $mindex create_array$$
1268 
1269 
1270 $head Syntax$$
1271 $icode%array% = thread_alloc::create_array<%Type%>(%size_min%, %size_out%)%$$.
1272 
1273 $head Purpose$$
1274 Create a new raw array using $cref thread_alloc$$ memory allocator
1275 (works well in a multi-threading environment)
1276 and call default constructor for each element.
1277 
1278 $head Type$$
1279 The type of the elements of the array.
1280 
1281 $head size_min$$
1282 This argument has prototype
1283 $codei%
1284  size_t %size_min%
1285 %$$
1286 This is the minimum number of elements that there can be
1287 in the resulting $icode array$$.
1288 
1289 $head size_out$$
1290 This argument has prototype
1291 $codei%
1292  size_t& %size_out%
1293 %$$
1294 The input value of this argument does not matter.
1295 Upon return, it is the actual number of elements
1296 in $icode array$$
1297 ($icode% size_min %<=% size_out%$$).
1298 
1299 $head array$$
1300 The return value $icode array$$ has prototype
1301 $codei%
1302  %Type%* %array%
1303 %$$
1304 It is array with $icode size_out$$ elements.
1305 The default constructor for $icode Type$$ is used to initialize the
1306 elements of $icode array$$.
1307 Note that $cref/delete_array/ta_delete_array/$$
1308 should be used to destroy the array when it is no longer needed.
1309 
1310 $head Delta$$
1311 The amount of memory $cref/inuse/ta_inuse/$$ by the current thread,
1312 will increase $icode delta$$ where
1313 $codei%
1314  sizeof(%Type%) * (%size_out% + 1) > %delta% >= sizeof(%Type%) * %size_out%
1315 %$$
1316 The $cref/available/ta_available/$$ memory will decrease by $icode delta$$,
1317 (and the allocation will be faster)
1318 if a previous allocation with $icode size_min$$ between its current value
1319 and $icode size_out$$ is available.
1320 
1321 $head Alignment$$
1322 We call a memory allocation aligned if the address is a multiple
1323 of the number of bytes in a $code size_t$$ value.
1324 If the system $code new$$ allocator is aligned, then $icode array$$
1325 pointer is also aligned.
1326 
1327 $head Example$$
1328 $cref thread_alloc.cpp$$
1329 
1330 $end
1331 */
1332  /*!
1333  Use thread_alloc to allocate an array, then call default construtor
1334  for each element.
1335 
1336  \tparam Type
1337  The type of the elements of the array.
1338 
1339  \param size_min [in]
1340  The minimum number of elements in the array.
1341 
1342  \param size_out [out]
1343  The actual number of elements in the array.
1344 
1345  \return
1346  pointer to the first element of the array.
1347  The default constructor is used to initialize
1348  all the elements of the array.
1349 
1350  \par
1351  The \c extra_ field, in the \c thread_alloc node before the return value,
1352  is set to size_out.
1353  */
1354  template <class Type>
1355  static Type* create_array(size_t size_min, size_t& size_out)
1356  { // minimum number of bytes to allocate
1357  size_t min_bytes = size_min * sizeof(Type);
1358  // do the allocation
1359  size_t num_bytes;
1360  void* v_ptr = get_memory(min_bytes, num_bytes);
1361  // This is where the array starts
1362  Type* array = reinterpret_cast<Type*>(v_ptr);
1363  // number of Type values in the allocation
1364  size_out = num_bytes / sizeof(Type);
1365  // store this number in the extra field
1366  block_t* node = reinterpret_cast<block_t*>(v_ptr) - 1;
1367  node->extra_ = size_out;
1368 
1369  // call default constructor for each element
1370  size_t i;
1371  for(i = 0; i < size_out; i++)
1372  new(array + i) Type();
1373 
1374  return array;
1375  }
1376 /* -----------------------------------------------------------------------
1377 $begin ta_delete_array$$
1378 $spell
1379  inuse
1380  thread_alloc
1381  sizeof
1382  deallocate
1383 $$
1384 
1385 $section Deallocate An Array and Call Destructor for its Elements$$
1386 $mindex delete_array$$
1387 
1388 
1389 $head Syntax$$
1390 $codei%thread_alloc::delete_array(%array%)%$$.
1391 
1392 $head Purpose$$
1393 Returns memory corresponding to an array created by
1394 (create by $cref/create_array/ta_create_array/$$) to the
1395 $cref/available/ta_available/$$ memory pool for the current thread.
1396 
1397 $head Type$$
1398 The type of the elements of the array.
1399 
1400 $head array$$
1401 The argument $icode array$$ has prototype
1402 $codei%
1403  %Type%* %array%
1404 %$$
1405 It is a value returned by $cref/create_array/ta_create_array/$$ and not yet deleted.
1406 The $icode Type$$ destructor is called for each element in the array.
1407 
1408 $head Thread$$
1409 The $cref/current thread/ta_thread_num/$$ must be the
1410 same as when $cref/create_array/ta_create_array/$$ returned the value $icode array$$.
1411 There is an exception to this rule:
1412 when the current execution mode is sequential
1413 (not $cref/parallel/ta_in_parallel/$$) the current thread number does not matter.
1414 
1415 $head Delta$$
1416 The amount of memory $cref/inuse/ta_inuse/$$ will decrease by $icode delta$$,
1417 and the $cref/available/ta_available/$$ memory will increase by $icode delta$$,
1418 where $cref/delta/ta_create_array/Delta/$$
1419 is the same as for the corresponding call to $code create_array$$.
1420 
1421 $head Example$$
1422 $cref thread_alloc.cpp$$
1423 
1424 $end
1425 */
1426  /*!
1427  Return Memory Used for an Array to the Available Pool
1428  (include destructor call for each element).
1429 
1430  \tparam Type
1431  The type of the elements of the array.
1432 
1433  \param array [in]
1434  A value returned by \c create_array that has not yet been deleted.
1435  The \c Type destructor is used to destroy each of the elements
1436  of the array.
1437 
1438  \par
1439  Durring parallel execution, the current thread must be the same
1440  as during the corresponding call to \c create_array.
1441  */
1442  template <class Type>
1443  static void delete_array(Type* array)
1444  { // determine the number of values in the array
1445  block_t* node = reinterpret_cast<block_t*>(array) - 1;
1446  size_t size = node->extra_;
1447 
1448  // call destructor for each element
1449  size_t i;
1450  for(i = 0; i < size; i++)
1451  (array + i)->~Type();
1452 
1453  // return the memory to the available pool for this thread
1454  thread_alloc::return_memory( reinterpret_cast<void*>(array) );
1455  }
1456 /* -----------------------------------------------------------------------
1457 $begin ta_free_all$$
1458 $spell
1459  alloc
1460  bool
1461  inuse
1462 $$
1463 
1464 $section Free All Memory That Was Allocated for Use by thread_alloc$$
1465 
1466 
1467 $head Syntax$$
1468 $icode%ok% = thread_alloc::free_all()%$$.
1469 
1470 $head Purpose$$
1471 Returns all memory that was used by $code thread_alloc$$ to the system.
1472 
1473 $head ok$$
1474 The return value $icode ok$$ has prototype
1475 $codei%
1476  bool %ok%
1477 %$$
1478 Its value will be $code true$$ if all the memory can be freed.
1479 This requires that for all $icode thread$$ indices, there is no memory
1480 $cref/inuse/ta_inuse/$$; i.e.,
1481 $codei%
1482  0 == thread_alloc::inuse(%thread%)
1483 %$$
1484 Otherwise, the return value will be false.
1485 
1486 $head Restrictions$$
1487 This function cannot be called while in parallel mode.
1488 
1489 $head Example$$
1490 $cref thread_alloc.cpp$$
1491 $end
1492 */
1493  /*!
1494  Return to the system all thread_alloc memory that is not currently inuse.
1495 
1496  \return
1497  If no \c thread_alloc memory is currently inuse,
1498  all memory is returned to the system and the return value is true.
1499  Otherwise the return value is false.
1500  */
1501  static bool free_all(void)
1503  ! in_parallel(),
1504  "free_all cannot be used while in parallel execution"
1505  );
1506  bool ok = true;
1507  size_t thread = CPPAD_MAX_NUM_THREADS;
1508  while(thread--)
1509  { ok &= inuse(thread) == 0;
1510  free_available(thread);
1511  }
1512  return ok;
1513  }
1514 };
1515 
1516 
1517 } // END_CPPAD_NAMESPACE
1518 
1519 // preprocessor symbols local to this file
1520 # undef CPPAD_MAX_NUM_CAPACITY
1521 # undef CPPAD_MIN_DOUBLE_CAPACITY
1522 # undef CPPAD_TRACE_CAPACITY
1523 # undef CPPAD_TRACE_THREAD
1524 # endif
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.