CppAD: A C++ Algorithmic Differentiation Package  20130918
thread_alloc.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_THREAD_ALLOC_INCLUDED
00003 # define CPPAD_THREAD_ALLOC_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 # include <sstream>
00017 # include <limits>
00018 # include <memory>
00019 
00020 
00021 # ifdef _MSC_VER
00022 // Supress warning that Microsoft compiler changed its behavior and is now 
00023 // doing the correct thing at the statement:
00024 //             new(array + i) Type();
00025 # pragma warning(disable:4345)
00026 # endif
00027 
00028 # include <cppad/local/cppad_assert.hpp>
00029 # include <cppad/local/define.hpp>
00030 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00031 /*!
00032 \file thread_alloc.hpp
00033 File used to define the CppAD multi-threading allocaor class
00034 */
00035 
00036 /*!
00037 \def CPPAD_MAX_NUM_CAPACITY
00038 Maximum number of different capacities the allocator will attempt.
00039 This must be larger than the log base two of numeric_limit<size_t>::max().
00040 */
00041 # define CPPAD_MAX_NUM_CAPACITY 100
00042 
00043 /*!
00044 \def CPPAD_MIN_DOUBLE_CAPACITY
00045 Minimum number of double values that will fit in an allocation.
00046 */
00047 # define CPPAD_MIN_DOUBLE_CAPACITY 16
00048 
00049 /*!
00050 \def CPPAD_TRACE_CAPACITY
00051 If NDEBUG is not defined, print all calls to \c get_memory and \c return_memory
00052 that correspond to this capacity and thread CPPAD_TRACE_THREAD.
00053 (Note that if CPPAD_TRACE_CAPACITY is zero, or any other value not in the list
00054 of capacities, no tracing will be done.)
00055 */
00056 # define CPPAD_TRACE_CAPACITY 0
00057 
00058 /*!
00059 \def CPPAD_TRACE_THREAD
00060 If NDEBUG is not defined, print all calls to \c get_memory and \c return_memory
00061 that correspond to this thead and capacity CPPAD_TRACE_CAPACITY.
00062 */
00063 # define CPPAD_TRACE_THREAD 0
00064 
00065 /*
00066 Note that Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for 
00067 objects with static storage duration (3.7.1) shall be zero-initialized
00068 (8.5) before any other initialization takes place."
00069 */
00070 
00071 /*!
00072 Capacity vector for memory allocation block sizes.
00073 
00074 Only one of these objects should be created and used as a
00075 static variable inside of the \c thread_alloc::capacity_info function.
00076 */
00077 
00078 /*!
00079 Allocator class that works well with an multi-threading environment.
00080 */
00081 class thread_alloc{
00082 // ============================================================================
00083 private:
00084      
00085      class capacity_t {
00086      public:
00087           /// number of capacity values actually used
00088           size_t number;
00089           /// the different capacity values
00090           size_t value[CPPAD_MAX_NUM_CAPACITY];
00091           /// ctor
00092           capacity_t(void)
00093           {    // Cannot figure out how to call thread_alloc::in_parallel here. 
00094                // CPPAD_ASSERT_UNKNOWN( 
00095                //   ! thread_alloc::in_parallel() , "thread_alloc: "
00096                //   "parallel mode and parallel_setup not yet called."
00097                // );
00098                number           = 0;
00099                size_t capacity  = CPPAD_MIN_DOUBLE_CAPACITY * sizeof(double);
00100                while( capacity < std::numeric_limits<size_t>::max() / 2 )
00101                {    CPPAD_ASSERT_UNKNOWN( number < CPPAD_MAX_NUM_CAPACITY );
00102                     value[number++] = capacity;
00103                     // next capactiy is 3/2 times the current one
00104                     capacity        = 3 * ( (capacity + 1) / 2 );
00105                }          
00106                CPPAD_ASSERT_UNKNOWN( number > 0 );
00107           }
00108      };
00109 
00110      class block_t {
00111      public:
00112           /// extra information (currently used by create and delete array)
00113           size_t             extra_;
00114           /// an index that uniquely idenfifies both thread and capacity
00115           size_t             tc_index_;
00116           /// pointer to the next memory allocation with the the same tc_index_
00117           void*              next_;
00118           // -----------------------------------------------------------------
00119           /// make default constructor private. It is only used by constructor
00120           /// for `root arrays below.
00121           block_t(void) : extra_(0), tc_index_(0), next_(CPPAD_NULL) 
00122           { }
00123      };
00124 
00125      // ---------------------------------------------------------------------
00126      /// Vector of fixed capacity values for this allocator
00127      static const capacity_t* capacity_info(void)
00128      {    CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
00129           static const capacity_t capacity;
00130           return &capacity;
00131      }
00132      // ---------------------------------------------------------------------
00133      /// Structure of information for each thread
00134      struct thread_alloc_info {
00135           /// count of available bytes for this thread 
00136           size_t  count_inuse_;
00137           /// count of inuse bytes for this thread 
00138           size_t  count_available_;
00139           /// root of available list for this thread and each capacity
00140           block_t root_available_[CPPAD_MAX_NUM_CAPACITY];
00141           /// root of inuse list for this thread and each capacity
00142           /// If NDEBUG is true, this memory is not used, but it still
00143           /// helps separate this structure from one for the next thread.
00144           block_t root_inuse_[CPPAD_MAX_NUM_CAPACITY];
00145      };
00146      // ---------------------------------------------------------------------
00147      /*!
00148      Set and Get hold available memory flag.
00149 
00150      \param set [in]
00151      if true, the value returned by this return is changed.
00152 
00153      \param new_value [in]
00154      if \a set is true, this is the new value returned by this routine.
00155      Otherwise, \c new_value is ignored.
00156 
00157      \return
00158      the current setting for this routine (which is initially false).
00159      */
00160      static bool set_get_hold_memory(bool set, bool new_value = false)
00161      {    static bool value = false;
00162           if( set )
00163                value = new_value;
00164           return value;
00165      }
00166      // ---------------------------------------------------------------------
00167      /*!
00168      Get pointer to the information for this thread.
00169 
00170      \param thread [in]
00171      Is the thread number for this information pointer.
00172 
00173      \param clear
00174      If \a clear is true, then the information pointer for this thread
00175      is deleted and the \c CPPAD_NULL pointer is returned.
00176      There must be no memory currently in either the inuse or avaialble
00177      lists when this routine is called.
00178 
00179      \return
00180      is the current informaiton pointer for this thread.
00181      If \a clear is false, and the current pointer is CPPAD_NULL,
00182      a new infromation record is allocated and its pointer returned.
00183      In this case, if \c info is the retured pointer, 
00184      <code>info->count_inuse == 0</code> and
00185      <code>info->count_available == 0</code>.
00186      In addition,
00187      for <code>c = 0 , ... , CPPAD_MAX_NUM_CAPACITY-1</code>
00188      <code>info->root_inuse_[c].next_ == CPPAD_NULL</code> and
00189      <code>info->root_available_[c].next_ == CPPAD_NULL</code>.
00190      */
00191      static thread_alloc_info* thread_info(
00192           size_t             thread          ,
00193           bool               clear = false   )
00194      {    static thread_alloc_info* all_info[CPPAD_MAX_NUM_THREADS];
00195           static thread_alloc_info  zero_info;
00196 
00197           CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
00198 
00199           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );
00200 
00201           thread_alloc_info* info = all_info[thread];
00202           if( clear )
00203           {    if( info != CPPAD_NULL )
00204                {
00205 # ifndef NDEBUG
00206                     CPPAD_ASSERT_UNKNOWN(
00207                          info->count_inuse_     == 0 &&
00208                          info->count_available_ == 0
00209                     );
00210                     for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)
00211                     {    CPPAD_ASSERT_UNKNOWN(
00212                               info->root_inuse_[c].next_     == CPPAD_NULL &&
00213                               info->root_available_[c].next_ == CPPAD_NULL
00214                          );
00215                     }
00216 # endif
00217                     if( thread != 0 )
00218                          ::operator delete( reinterpret_cast<void*>(info) );
00219                     info             = CPPAD_NULL;
00220                     all_info[thread] = info;
00221                }
00222           }
00223           else if( info == CPPAD_NULL )
00224           {    if( thread == 0 )
00225                     info = &zero_info;
00226                else
00227                {    size_t size = sizeof(thread_alloc_info);
00228                     void* v_ptr = ::operator new(size);
00229                     info        = reinterpret_cast<thread_alloc_info*>(v_ptr);
00230                }
00231                all_info[thread] = info;
00232 
00233                // initialize the information record
00234                for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)
00235                {    info->root_inuse_[c].next_       = CPPAD_NULL;
00236                     info->root_available_[c].next_   = CPPAD_NULL;
00237                }
00238                info->count_inuse_     = 0;
00239                info->count_available_ = 0;
00240           }
00241           return info;
00242      }
00243      // -----------------------------------------------------------------------
00244      /*!
00245      Increase the number of bytes of memory that are currently in use; i.e.,
00246      that been obtained with \c get_memory and not yet returned. 
00247 
00248      \param inc [in]
00249      amount to increase memory in use.
00250 
00251      \param thread [in]
00252      Thread for which we are increasing the number of bytes in use
00253      (must be less than \c num_threads).
00254      Durring parallel execution, this must be the thread 
00255      that is currently executing.
00256      */
00257      static void inc_inuse(size_t inc, size_t thread)
00258      {    
00259           CPPAD_ASSERT_UNKNOWN( thread < num_threads() );
00260           CPPAD_ASSERT_UNKNOWN( 
00261                thread == thread_num() || (! in_parallel()) 
00262           );
00263           thread_alloc_info* info = thread_info(thread);
00264           
00265           // do the addition
00266           size_t result = info->count_inuse_ + inc;
00267           CPPAD_ASSERT_UNKNOWN( result >= info->count_inuse_ );
00268 
00269           info->count_inuse_ = result;
00270      }
00271      // -----------------------------------------------------------------------
00272      /*!
00273      Increase the number of bytes of memory that are currently avaialble; i.e.,
00274      have been obtained obtained from the system and are being held future use.
00275 
00276      \copydetails inc_inuse
00277      */
00278      static void inc_available(size_t inc, size_t thread)
00279      {    
00280           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
00281           CPPAD_ASSERT_UNKNOWN( 
00282                thread == thread_num() || (! in_parallel()) 
00283           );
00284           thread_alloc_info* info = thread_info(thread);
00285           // do the addition
00286           size_t result = info->count_available_ + inc;
00287           CPPAD_ASSERT_UNKNOWN( result >= info->count_available_ );
00288 
00289           info->count_available_ = result;
00290      }
00291      // -----------------------------------------------------------------------
00292      /*!
00293      Decrease the number of bytes of memory that are currently in use; i.e.,
00294      that been obtained with \c get_memory and not yet returned. 
00295 
00296      \param dec [in]
00297      amount to decrease number of bytes in use.
00298 
00299      \param thread [in]
00300      Thread for which we are decreasing the number of bytes in use
00301      (must be less than \c num_threads).
00302      Durring parallel execution, this must be the thread 
00303      that is currently executing.
00304      */
00305      static void dec_inuse(size_t dec, size_t thread)
00306      {    
00307           CPPAD_ASSERT_UNKNOWN(
00308                thread < num_threads() || (! in_parallel())
00309           );
00310           CPPAD_ASSERT_UNKNOWN( 
00311                thread == thread_num() || (! in_parallel()) 
00312           );
00313           thread_alloc_info* info = thread_info(thread);
00314 
00315           // do the subtraction
00316           CPPAD_ASSERT_UNKNOWN( info->count_inuse_ >= dec );
00317           info->count_inuse_ = info->count_inuse_ - dec;
00318      }
00319      // -----------------------------------------------------------------------
00320      /*!
00321      Decrease the number of bytes of memory that are currently avaialble; i.e.,
00322      have been obtained obtained from the system and are being held future use.
00323 
00324      \copydetails dec_inuse
00325      */
00326      static void dec_available(size_t dec, size_t thread)
00327      {    
00328           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
00329           CPPAD_ASSERT_UNKNOWN( 
00330                thread == thread_num() || (! in_parallel()) 
00331           );
00332           thread_alloc_info* info = thread_info(thread);
00333           // do the subtraction
00334           CPPAD_ASSERT_UNKNOWN( info->count_available_ >= dec );
00335           info->count_available_ =  info->count_available_ - dec;
00336      }
00337 
00338      // ----------------------------------------------------------------------
00339      /*!
00340      Set and get the number of threads that are sharing memory.
00341 
00342      \param number_new 
00343      If \c number is zero, we are only retreiving the current maximum
00344      number of threads. Otherwise, we are setting and retreiving
00345      maximum number of threads.
00346 
00347      \return
00348      the number of threads that are sharing memory.
00349      If \c number_new is non-zero, the return value is equal to 
00350      \c number_new.
00351      */
00352      static size_t set_get_num_threads(size_t number_new)
00353      {    static size_t number_user = 1;
00354 
00355           CPPAD_ASSERT_UNKNOWN( number_new <= CPPAD_MAX_NUM_THREADS );
00356           CPPAD_ASSERT_UNKNOWN( ! in_parallel() || (number_new == 0) );
00357 
00358           // case where we are changing the number of threads
00359           if( number_new != 0 )
00360                number_user = number_new;
00361 
00362           return number_user;
00363      }
00364      /*!
00365      Set and call the routine that determine if we are in parallel 
00366      execution mode.
00367 
00368      \return 
00369      value retuned by most recent setting for \a parallel_new.
00370      If \a set is true,
00371      or the most recent setting is \c CPPAD_NULL (its initial value),
00372      the return value is false.
00373      Otherwise the function corresponding to the most recent setting
00374      is called and its value returned by \c set_get_in_parallel.
00375 
00376      \param parallel_new [in]
00377      If \a set is false, \a parallel_new it is not used.
00378      Otherwise, the current value of \c parallel_new becomes the
00379      most recent setting for in_parallel.
00380 
00381      \param set
00382      If \a set is true, then \a parallel_new is becomes the most
00383      recent setting for this \c set_get_in_parallel.
00384      */
00385      static bool set_get_in_parallel(
00386           bool (*parallel_new)(void) ,
00387           bool set = false           )
00388      {    static bool (*parallel_user)(void) = CPPAD_NULL;
00389 
00390           if( set )
00391           {    parallel_user = parallel_new;
00392                return false;
00393           }
00394 
00395           if( parallel_user == CPPAD_NULL )
00396                return false;
00397 
00398           return parallel_user();
00399      }
00400      /*!
00401      Set and call the routine that determine the current thread number.
00402 
00403      \return 
00404      returns value for the most recent setting for \a thread_num_new.
00405      If \a set is true,
00406      or the most recent setting is \c CPPAD_NULL (its initial value),
00407      the return value is zero.
00408      Otherwise the routine corresponding to the most recent setting
00409      is called and its value returned by \c set_get_thread_num.
00410 
00411      \param thread_num_new [in]
00412      If \a set is false, \a thread_num_new it is not used.
00413      Otherwise, the current value of \c thread_num_new becomes the
00414      most recent setting for thread_num.
00415 
00416      \param set
00417      If \a set is true, then \a thread_num_new is becomes the most
00418      recent setting for this \c set_get_thread_num.
00419      */
00420      static size_t set_get_thread_num(
00421           size_t (*thread_num_new)(void)  ,
00422           bool set = false                )
00423      {    static size_t (*thread_num_user)(void) = CPPAD_NULL;
00424 
00425           if( set )
00426           {    thread_num_user = thread_num_new;
00427                return 0;
00428           }
00429 
00430           if( thread_num_user == CPPAD_NULL )
00431                return 0;
00432 
00433           size_t thread = thread_num_user();
00434           CPPAD_ASSERT_KNOWN(
00435                thread < set_get_num_threads(0) ,
00436                "parallel_setup: thread_num() >= num_threads"
00437           );
00438           return thread;
00439      }
00440 // ============================================================================
00441 public:
00442 /*
00443 $begin ta_parallel_setup$$
00444 $spell
00445      alloc
00446      num
00447      bool
00448 $$
00449 $section Setup thread_alloc For Use in Multi-Threading Environment$$
00450 
00451 $index setup, thread_alloc$$
00452 $index thread_alloc, setup$$
00453 $index parallel, setup$$
00454 $index setup, parallel$$
00455 
00456 $index num_threads$$
00457 $index in_parallel$$
00458 $index thread_num$$
00459 
00460 $index multi-threading, initialize$$
00461 $index initialize, multi-threading$$
00462 
00463 $head Syntax$$
00464 $codei%thread_alloc::parallel_setup(%num_threads%, %in_parallel%, %thread_num%)
00465 %$$
00466 
00467 $head Purpose$$
00468 By default there is only one thread and all execution is in sequential mode,
00469 i.e., multiple threads are not sharing the same memory; i.e.
00470 not in parallel mode.
00471 
00472 $head Speed$$
00473 It should be faster, even when $icode num_thread$$ is equal to one,
00474 for $code thread_alloc$$ to hold onto memory.
00475 This can be accomplished using the function call
00476 $codei%
00477      thread_alloc::hold_memory(true)
00478 %$$
00479 see $cref/hold_memory/ta_hold_memory/$$.
00480 
00481 $head num_threads$$
00482 This argument has prototype
00483 $codei%
00484      size_t %num_threads%
00485 %$$ 
00486 and must be greater than zero.
00487 It specifies the number of threads that are sharing memory.
00488 The case $icode%num_threads% == 1%$$ is a special case that is 
00489 used to terminate a multi-threading environment.
00490 
00491 $head in_parallel$$
00492 This function has prototype
00493 $codei%
00494      bool %in_parallel%(void) 
00495 %$$
00496 It must return $code true$$ if there is more than one thread
00497 currently executing.
00498 Otherwise it can return false.
00499 $pre
00500 
00501 $$
00502 In the special case where $icode%num_threads% == 1%$$,
00503 the routine $icode in_parallel$$ is not used.
00504 
00505 $head thread_num$$
00506 This function has prototype
00507 $codei%
00508      size_t %thread_num%(void) 
00509 %$$
00510 It must return a thread number that uniquely identifies the
00511 currently executing thread. 
00512 Furthermore
00513 $codei%
00514      0 <= %thread_num%() < %num_threads%
00515 %$$.
00516 In the special case where $icode%num_threads% == 1%$$,
00517 the routine $icode thread_num$$ is not used.
00518 $pre
00519 
00520 $$
00521 Note that this function is called by other routines so,
00522 as soon as a new thread is executing,
00523 one must be certain that $icode thread_num()$$ will
00524 work for that thread.
00525 
00526 $head Restrictions$$
00527 The function $code parallel_setup$$ must be called before 
00528 the program enters $cref/parallel/ta_in_parallel/$$ execution mode.
00529 In addition, this function cannot be called while in parallel mode.
00530 
00531 $head Example$$
00532 The files 
00533 $cref simple_ad_openmp.cpp$$, 
00534 $cref simple_ad_bthread.cpp$$, and
00535 $cref simple_ad_pthread.cpp$$, 
00536 contain examples and tests that use this function.   
00537 
00538 $end
00539 */
00540      /*!
00541      Set thread_alloc up for parallel mode usage.
00542 
00543      \param num_threads [in]
00544      Is the number of thread that may be executing at the same time.
00545 
00546      \param in_parallel [in]
00547      Is the routine that determines if we are in parallel mode or not.
00548 
00549      \param thread_num [in]
00550      Is the routine that determines the current thread number
00551      (between zero and num_threads minus one).
00552      */
00553      static void parallel_setup(
00554           size_t num_threads         ,
00555           bool (*in_parallel)(void)  ,
00556           size_t (*thread_num)(void) )
00557      {
00558           // Special case where we go back to single thread mode right away
00559           // (previous settings may no longer be valid)
00560           if( num_threads == 1 )
00561           {    bool set = true;
00562                set_get_num_threads(num_threads);
00563                set_get_in_parallel(CPPAD_NULL, set);
00564                set_get_thread_num(CPPAD_NULL, set);
00565                return;
00566           }
00567 
00568           CPPAD_ASSERT_KNOWN( 
00569                num_threads <= CPPAD_MAX_NUM_THREADS ,
00570                "parallel_setup: num_threads is too large"
00571           );
00572           CPPAD_ASSERT_KNOWN( 
00573                num_threads != 0 ,
00574                "parallel_setup: num_threads == zero"
00575           );
00576           CPPAD_ASSERT_KNOWN( 
00577                in_parallel != CPPAD_NULL ,
00578                "parallel_setup: num_threads != 1 and in_parallel == CPPAD_NULL"
00579           );
00580           CPPAD_ASSERT_KNOWN( 
00581                thread_num != CPPAD_NULL ,
00582                "parallel_setup: num_threads != 1 and thread_num == CPPAD_NULL"
00583           );
00584 
00585           // Make sure that constructors for all static variables in this file 
00586           // are called in sequential mode.  
00587           for(size_t thread = 0; thread < num_threads; thread++)
00588                thread_info(thread);
00589           capacity_info();
00590           size_t cap_bytes;
00591           void* v_ptr = get_memory(0, cap_bytes);
00592 
00593           // free memory allocated by call to get_memory above
00594           return_memory(v_ptr);
00595           free_available( set_get_thread_num(CPPAD_NULL) );
00596 
00597           // delay this so thread_num() call above is in previous mode
00598           // (current setings may not yet be valid)
00599           if( num_threads > 1 )
00600           {    bool set = true;
00601                set_get_num_threads(num_threads);
00602                set_get_in_parallel(in_parallel, set);
00603                set_get_thread_num(thread_num, set);
00604           }
00605      }
00606 /*
00607 $begin ta_num_threads$$
00608 $spell
00609      inv
00610      CppAD
00611      num
00612      alloc
00613 $$
00614 $section Get Number of Threads$$
00615 
00616 $index num_threads, thread_alloc$$
00617 $index thread_alloc, num_threads$$
00618 $index threads, number of$$
00619 
00620 $head Syntax$$
00621 $icode%number% = thread_alloc::num_threads()%$$
00622 
00623 $head Purpose$$
00624 Determine the number of threads as set during $cref/parallel_setup/ta_parallel_setup/$$.
00625 
00626 $head number$$
00627 The return value $icode number$$ has prototype
00628 $codei%
00629      size_t %number%
00630 %$$ 
00631 and is equal to the value of 
00632 $cref/num_threads/ta_parallel_setup/num_threads/$$
00633 in the previous call to $icode parallel_setup$$.
00634 If there was no such previous call, the value one is returned.
00635 
00636 $head Example$$
00637 The example and test $cref thread_alloc.cpp$$ uses this routine.
00638 
00639 $end
00640 */
00641      /*!
00642      Get the current number of threads that thread_alloc can use.
00643      */
00644      static size_t num_threads(void)
00645      {    return set_get_num_threads(0); }
00646 /* -----------------------------------------------------------------------
00647 $begin ta_in_parallel$$
00648 
00649 $section Is The Current Execution in Parallel Mode$$
00650 $spell
00651      thread_alloc
00652      bool
00653 $$
00654 
00655 $index in_parallel, thread_alloc$$
00656 $index thread_alloc, in_parallel$$
00657 $index parallel, execution$$
00658 $index execution, parallel$$
00659 $index sequential, execution$$
00660 
00661 $head Syntax$$
00662 $icode%flag% = thread_alloc::in_parallel()%$$
00663 
00664 $head Purpose$$
00665 Some of the $cref thread_alloc$$ allocation routines have different
00666 specifications for parallel (not sequential) execution mode.
00667 This routine enables you to determine if the current execution mode
00668 is sequential or parallel.
00669 
00670 $head flag$$
00671 The return value has prototype
00672 $codei%
00673      bool %flag%
00674 %$$
00675 It is true if the current execution is in parallel mode 
00676 (possibly multi-threaded) and false otherwise (sequential mode).
00677 
00678 $head Example$$
00679 $cref thread_alloc.cpp$$
00680 
00681 $end
00682 */
00683      /// Are we in a parallel execution state; i.e., is it possible that
00684      /// other threads are currently executing. 
00685      static bool in_parallel(void)
00686      {    return set_get_in_parallel(0); }
00687 /* -----------------------------------------------------------------------
00688 $begin ta_thread_num$$
00689 $spell
00690      CppAD
00691      num
00692      thread_alloc
00693      cppad.hpp
00694 $$
00695 
00696 $section Get the Current Thread Number$$
00697 
00698 $index thread_num, thread_alloc$$
00699 $index thread_alloc, thread_num$$
00700 $index thread, current$$
00701 $index current, thread$$
00702 
00703 $head Syntax$$
00704 $icode%thread% = thread_alloc::thread_num()%$$
00705 
00706 $head Purpose$$
00707 Some of the $cref thread_alloc$$ allocation routines have a thread number.
00708 This routine enables you to determine the current thread.
00709 
00710 $head thread$$
00711 The return value $icode thread$$ has prototype
00712 $codei%
00713      size_t %thread%
00714 %$$
00715 and is the currently executing thread number.
00716 If $code _OPENMP$$ is not defined, $icode thread$$ is zero.
00717 
00718 $head Example$$
00719 $cref thread_alloc.cpp$$
00720 
00721 $end
00722 */
00723      /// Get current thread number 
00724      static size_t thread_num(void)
00725      {    return set_get_thread_num(CPPAD_NULL); }
00726 /* -----------------------------------------------------------------------
00727 $begin ta_get_memory$$
00728 $spell
00729      std
00730      num
00731      ptr
00732      thread_alloc
00733 $$
00734 
00735 $section Get At Least A Specified Amount of Memory$$
00736 
00737 $index thread_num, thread_alloc$$
00738 $index thread_alloc, thread_num$$
00739 $index memory, allocate$$
00740 $index allocate, memory$$
00741 
00742 $head Syntax$$
00743 $icode%v_ptr% = thread_alloc::get_memory(%min_bytes%, %cap_bytes%)%$$
00744 
00745 $head Purpose$$
00746 Use $cref thread_alloc$$ to obtain a minimum number of bytes of memory
00747 (for use by the $cref/current thread/ta_thread_num/$$).
00748 
00749 $head min_bytes$$
00750 This argument has prototype
00751 $codei%
00752      size_t %min_bytes%
00753 %$$
00754 It specifies the minimum number of bytes to allocate.
00755 This value must be less than
00756 $codep
00757      std::numeric_limits<size_t>::max() / 2
00758 $$
00759 
00760 $head cap_bytes$$
00761 This argument has prototype
00762 $codei%
00763      size_t& %cap_bytes%
00764 %$$
00765 It's input value does not matter.
00766 Upon return, it is the actual number of bytes (capacity) 
00767 that have been allocated for use,
00768 $codei%
00769      %min_bytes% <= %cap_bytes%
00770 %$$
00771 
00772 $head v_ptr$$
00773 The return value $icode v_ptr$$ has prototype
00774 $codei%
00775      void* %v_ptr%
00776 %$$
00777 It is the location where the $icode cap_bytes$$ of memory 
00778 that have been allocated for use begins.
00779 
00780 $head Allocation Speed$$
00781 This allocation should be faster if the following conditions hold:
00782 $list number$$
00783 The memory allocated by a previous call to $code get_memory$$ 
00784 is currently available for use.
00785 $lnext
00786 The current $icode min_bytes$$ is between 
00787 the previous $icode min_bytes$$ and previous $icode cap_bytes$$.
00788 $lend
00789 
00790 $head Example$$
00791 $cref thread_alloc.cpp$$
00792 
00793 $end
00794 */
00795      /*!
00796      Use thread_alloc to get a specified amount of memory.
00797 
00798      If the memory allocated by a previous call to \c get_memory is now 
00799      avaialable, and \c min_bytes is between its previous value
00800      and the previous \c cap_bytes, this memory allocation will have
00801      optimal speed. Otherwise, the memory allocation is more complicated and
00802      may have to wait for other threads to complete an allocation.
00803 
00804      \param min_bytes [in]
00805      The minimum number of bytes of memory to be obtained for use.
00806 
00807      \param cap_bytes [out]
00808      The actual number of bytes of memory obtained for use.
00809 
00810      \return
00811      pointer to the beginning of the memory allocated for use.
00812      */
00813      static void* get_memory(size_t min_bytes, size_t& cap_bytes)
00814      {    // see first_trace below 
00815           CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
00816 
00817           // check that number of requested bytes is not to large
00818           CPPAD_ASSERT_KNOWN(
00819                min_bytes < std::numeric_limits<size_t>::max() / 2 ,
00820                "get_memory(min_bytes, cap_bytes): min_bytes is too large"
00821           );
00822 
00823           size_t num_cap = capacity_info()->number;
00824           using std::cout;
00825           using std::endl;
00826 
00827           // determine the capacity for this request
00828           size_t c_index   = 0;
00829           const size_t* capacity_vec = capacity_info()->value;
00830           while( capacity_vec[c_index] < min_bytes )
00831           {    ++c_index;     
00832                CPPAD_ASSERT_UNKNOWN(c_index < num_cap );
00833           }
00834           cap_bytes = capacity_vec[c_index];
00835 
00836           // determine the thread, capacity, and info for this thread
00837           size_t thread            = thread_num();
00838           size_t tc_index          = thread * num_cap + c_index;
00839           thread_alloc_info* info  = thread_info(thread);
00840 
00841 # ifndef NDEBUG
00842           // trace allocation
00843           static bool first_trace = true;
00844           if(  cap_bytes == CPPAD_TRACE_CAPACITY && 
00845                thread    ==  CPPAD_TRACE_THREAD  && first_trace )
00846           {    cout << endl;  
00847                cout << "thread_alloc: Trace for Thread = " << thread;
00848                cout << " and capacity = " << cap_bytes << endl;
00849                if( first_trace )
00850                     first_trace = false;
00851           }
00852 
00853           // Root nodes for both lists. Note these are different for different 
00854           // threads because tc_index is different for different threads.
00855           block_t* inuse_root     = info->root_inuse_ + c_index;
00856 # endif
00857           block_t* available_root = info->root_available_ + c_index;
00858 
00859           // check if we already have a node we can use
00860           void* v_node              = available_root->next_;
00861           block_t* node             = reinterpret_cast<block_t*>(v_node);
00862           if( node != CPPAD_NULL )
00863           {    CPPAD_ASSERT_UNKNOWN( node->tc_index_ == tc_index );
00864 
00865                // remove node from available list
00866                available_root->next_ = node->next_;
00867 
00868                // return value for get_memory
00869                void* v_ptr = reinterpret_cast<void*>(node + 1);
00870 # ifndef NDEBUG
00871                // add node to inuse list
00872                node->next_           = inuse_root->next_;
00873                inuse_root->next_     = v_node;
00874 
00875                // trace allocation
00876                if(  cap_bytes == CPPAD_TRACE_CAPACITY && 
00877                     thread    ==  CPPAD_TRACE_THREAD   )
00878                {    cout << "get_memory:    v_ptr = " << v_ptr << endl; } 
00879 # endif
00880 
00881                // adjust counts
00882                inc_inuse(cap_bytes, thread);
00883                dec_available(cap_bytes, thread);
00884 
00885                // return pointer to memory, do not inclue thread_alloc information
00886                return v_ptr;
00887           }
00888 
00889           // Create a new node with thread_alloc information at front.
00890           // This uses the system allocator, which is thread safe, but slower,
00891           // because the thread might wait for a lock on the allocator.
00892           v_node          = ::operator new(sizeof(block_t) + cap_bytes);
00893           node            = reinterpret_cast<block_t*>(v_node);
00894           node->tc_index_ = tc_index;
00895           void* v_ptr     = reinterpret_cast<void*>(node + 1);
00896 
00897 # ifndef NDEBUG
00898           // add node to inuse list
00899           node->next_       = inuse_root->next_;
00900           inuse_root->next_ = v_node;
00901 
00902           // trace allocation
00903           if( cap_bytes == CPPAD_TRACE_CAPACITY && 
00904               thread    == CPPAD_TRACE_THREAD    )
00905           {    cout << "get_memory:    v_ptr = " << v_ptr << endl; }
00906 # endif
00907 
00908           // adjust counts
00909           inc_inuse(cap_bytes, thread);
00910 
00911           return v_ptr;
00912      }
00913 
00914 /* -----------------------------------------------------------------------
00915 $begin ta_return_memory$$
00916 $spell
00917      num
00918      ptr
00919      thread_alloc
00920 $$
00921 
00922 $section Return Memory to thread_alloc$$
00923 
00924 $index return_memory, thread_alloc$$
00925 $index thread_alloc, return_memory$$
00926 $index memory, available$$
00927 $index available, memory$$
00928 $index thread, available memory$$
00929 
00930 $head Syntax$$
00931 $codei%thread_alloc::return_memory(%v_ptr%)%$$
00932 
00933 $head Purpose$$
00934 If $cref/hold_memory/ta_hold_memory/$$ is false,
00935 the memory is returned to the system.
00936 Otherwise, the memory is retained by $cref thread_alloc$$ for quick future use
00937 by the thread that allocated to memory.
00938 
00939 $head v_ptr$$
00940 This argument has prototype
00941 $codei%
00942      void* %v_ptr%
00943 %$$.
00944 It must be a pointer to memory that is currently in use; i.e.
00945 obtained by a previous call to 
00946 $cref/get_memory/ta_get_memory/$$ and not yet returned.
00947 
00948 $head Thread$$
00949 Either the $cref/current thread/ta_thread_num/$$ must be the same as during
00950 the corresponding call to $cref/get_memory/ta_get_memory/$$,
00951 or the current execution mode must be sequential 
00952 (not $cref/parallel/ta_in_parallel/$$).
00953 
00954 $head NDEBUG$$
00955 If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster).
00956 Otherwise, a list of in use pointers is searched to make sure
00957 that $icode v_ptr$$ is in the list. 
00958 
00959 $head Example$$
00960 $cref thread_alloc.cpp$$
00961 
00962 $end
00963 */
00964      /*!
00965      Return memory that was obtained by \c get_memory.
00966      If  <code>num_threads() == 1</code>,
00967      the memory is returned to the system.
00968      Otherwise, it is retained by \c thread_alloc and available for use by 
00969      \c get_memory for this thread.
00970 
00971      \param v_ptr [in]
00972      Value of the pointer returned by \c get_memory and still in use.
00973      After this call, this pointer will available (and not in use).
00974 
00975      \par
00976      We must either be in sequential (not parallel) execution mode,
00977      or the current thread must be the same as for the corresponding call
00978      to \c get_memory.
00979      */
00980      static void return_memory(void* v_ptr)
00981      {    size_t num_cap   = capacity_info()->number;
00982 
00983           block_t* node    = reinterpret_cast<block_t*>(v_ptr) - 1;
00984           size_t tc_index  = node->tc_index_;
00985           size_t thread    = tc_index / num_cap;
00986           size_t c_index   = tc_index % num_cap;
00987           size_t capacity  = capacity_info()->value[c_index];
00988 
00989           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );
00990           CPPAD_ASSERT_KNOWN( 
00991                thread == thread_num() || (! in_parallel()),
00992                "Attempt to return memory for a different thread "
00993                "while in parallel mode"
00994           );
00995 
00996           thread_alloc_info* info = thread_info(thread);
00997 # ifndef NDEBUG
00998           // remove node from inuse list
00999           void* v_node         = reinterpret_cast<void*>(node);
01000           block_t* inuse_root  = info->root_inuse_ + c_index;
01001           block_t* previous    = inuse_root;
01002           while( (previous->next_ != CPPAD_NULL) & (previous->next_ != v_node) )
01003                previous = reinterpret_cast<block_t*>(previous->next_);     
01004 
01005           // check that v_ptr is valid
01006           if( previous->next_ != v_node )
01007           {    using std::endl;
01008                std::ostringstream oss;
01009                oss << "return_memory: attempt to return memory not in use";
01010                oss << endl;
01011                oss << "v_ptr    = " << v_ptr    << endl;   
01012                oss << "thread   = " << thread   << endl;   
01013                oss << "capacity = " << capacity << endl;   
01014                oss << "See CPPAD_TRACE_THREAD & CPPAD_TRACE_CAPACITY in";
01015                oss << endl << "# include <cppad/thread_alloc.hpp>" << endl;
01016                CPPAD_ASSERT_KNOWN(false, oss.str().c_str()  ); 
01017           }
01018 
01019           // trace option
01020           if( capacity==CPPAD_TRACE_CAPACITY && thread==CPPAD_TRACE_THREAD )
01021           {    std::cout << "return_memory: v_ptr = " << v_ptr << std::endl; }
01022 
01023           // remove v_ptr from inuse list
01024           previous->next_  = node->next_;
01025 # endif
01026           // capacity bytes are removed from the inuse pool
01027           dec_inuse(capacity, thread);
01028 
01029           // check for case where we just return the memory to the system
01030           if( ! set_get_hold_memory(false) )
01031           {    ::operator delete( reinterpret_cast<void*>(node) );
01032                return;
01033           }
01034 
01035           // add this node to available list for this thread and capacity
01036           block_t* available_root = info->root_available_ + c_index;
01037           node->next_             = available_root->next_;
01038           available_root->next_   = reinterpret_cast<void*>(node);
01039 
01040           // capacity bytes are added to the available pool
01041           inc_available(capacity, thread);
01042      }
01043 /* -----------------------------------------------------------------------
01044 $begin ta_free_available$$
01045 $spell
01046      num
01047      thread_alloc
01048 $$
01049 
01050 $section Free Memory Currently Available for Quick Use by a Thread$$
01051 $spell
01052      inuse
01053 $$
01054 
01055 $index free_available, thread_alloc$$
01056 $index thread_alloc, free_available$$
01057 $index free, available$$
01058 $index available, free$$
01059 $index thread, free memory$$
01060 
01061 $head Syntax$$
01062 $codei%thread_alloc::free_available(%thread%)%$$
01063 
01064 $head Purpose$$
01065 Return to the system all the memory that is currently being
01066 $cref/held/ta_hold_memory/$$ for quick use by the specified thread.
01067 
01068 $subhead Extra Memory$$
01069 In the case where $icode%thread% > 0%$$,
01070 some extra memory is used to track allocations by the specified thread.
01071 If 
01072 $codei%
01073      thread_alloc::inuse(%thread%) == 0
01074 %$$
01075 the extra memory is also returned to the system.
01076 
01077 $head thread$$
01078 This argument has prototype
01079 $codei%
01080      size_t %thread%
01081 %$$
01082 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
01083 or the current execution mode must be sequential 
01084 (not $cref/parallel/ta_in_parallel/$$).
01085 
01086 $head Example$$
01087 $cref thread_alloc.cpp$$
01088 
01089 $end
01090 */
01091      /*!
01092      Return all the memory being held as available for a thread to the system.
01093 
01094      \param thread [in]
01095      this thread that will no longer have any available memory after this call.
01096      This must either be the thread currently executing, or we must be 
01097      in sequential (not parallel) execution mode.
01098      */
01099      static void free_available(size_t thread)
01100      {    CPPAD_ASSERT_KNOWN(
01101                thread < CPPAD_MAX_NUM_THREADS,
01102                "Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS"
01103           );
01104           CPPAD_ASSERT_KNOWN( 
01105                thread == thread_num() || (! in_parallel()),
01106                "Attempt to free memory for a different thread "
01107                "while in parallel mode"
01108           );
01109      
01110           size_t num_cap = capacity_info()->number;
01111           if( num_cap == 0 )
01112                return;
01113           const size_t*     capacity_vec  = capacity_info()->value;
01114           size_t c_index;
01115           thread_alloc_info* info = thread_info(thread);
01116           for(c_index = 0; c_index < num_cap; c_index++)
01117           {    size_t capacity = capacity_vec[c_index];
01118                block_t* available_root = info->root_available_ + c_index;
01119                void* v_ptr             = available_root->next_;
01120                while( v_ptr != CPPAD_NULL )
01121                {    block_t* node = reinterpret_cast<block_t*>(v_ptr); 
01122                     void* next    = node->next_;
01123                     ::operator delete(v_ptr);
01124                     v_ptr         = next;
01125 
01126                     dec_available(capacity, thread);
01127                }
01128                available_root->next_ = CPPAD_NULL;
01129           }
01130           CPPAD_ASSERT_UNKNOWN( available(thread) == 0 );
01131           if( inuse(thread) == 0 )
01132           {    // clear the information for this thread
01133                thread_info(thread, true);
01134           }
01135      }
01136 /* -----------------------------------------------------------------------
01137 $begin ta_hold_memory$$
01138 $spell
01139      alloc
01140      num
01141 $$
01142 
01143 $section Control When Thread Alloc Retains Memory For Future Use$$
01144 $index thread_alloc, hold memory$$
01145 $index hold, thread_alloc memory$$
01146 $index memory, thread_alloc hold$$
01147 
01148 $head Syntax$$
01149 $codei%thread_alloc::hold_memory(%value%)%$$
01150 
01151 $head Purpose$$
01152 It should be faster, even when $icode num_thread$$ is equal to one,
01153 for $code thread_alloc$$ to hold onto memory.
01154 Calling $icode hold_memory$$ with $icode value$$ equal to true,
01155 instructs $code thread_alloc$$ to hold onto memory,
01156 and put it in the $cref/available/ta_available/$$ pool,
01157 after each call to $cref/return_memory/ta_return_memory/$$. 
01158 
01159 $head value$$
01160 If $icode value$$ is true,
01161 $code thread_alloc$$ with hold onto memory for future quick use.
01162 If it is false, future calls to $cref/return_memory/ta_return_memory/$$
01163 will return the corresponding memory to the system.
01164 By default (when $code hold_memory$$ has not been called)
01165 $code thread_alloc$$ does not hold onto memory.
01166 
01167 $head free_available$$
01168 Memory that is being held by $code thread_alloc$$ can be returned
01169 to the system using $cref/free_available/ta_free_available/$$.
01170 
01171 $end
01172 */
01173      /*!
01174      Change the thread_alloc hold memory setting.
01175 
01176      \param value [in]
01177      New value for the thread_alloc hold memory setting.
01178      */
01179      static void hold_memory(bool value)
01180      {    bool set = true;
01181           set_get_hold_memory(set, value);
01182      }    
01183      
01184 /* -----------------------------------------------------------------------
01185 $begin ta_inuse$$
01186 $spell
01187      num
01188      inuse
01189      thread_alloc
01190 $$
01191 
01192 $section Amount of Memory a Thread is Currently Using$$
01193 
01194 $index inuse, thread_alloc$$
01195 $index thread_alloc, inuse$$
01196 $index use, memory$$
01197 $index thread, memory inuse$$
01198 
01199 $head Syntax$$
01200 $icode%num_bytes% = thread_alloc::inuse(%thread%)%$$
01201 
01202 $head Purpose$$
01203 Memory being managed by $cref thread_alloc$$ has two states,
01204 currently in use by the specified thread,
01205 and quickly available for future use by the specified thread.
01206 This function informs the program how much memory is in use.
01207 
01208 $head thread$$
01209 This argument has prototype
01210 $codei%
01211      size_t %thread%
01212 %$$
01213 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
01214 or the current execution mode must be sequential 
01215 (not $cref/parallel/ta_in_parallel/$$).
01216 
01217 $head num_bytes$$
01218 The return value has prototype
01219 $codei%
01220      size_t %num_bytes%
01221 %$$
01222 It is the number of bytes currently in use by the specified thread.
01223 
01224 $head Example$$
01225 $cref thread_alloc.cpp$$
01226 
01227 $end
01228 */
01229      /*!
01230      Determine the amount of memory that is currently inuse.
01231 
01232      \param thread [in]
01233      Thread for which we are determining the amount of memory
01234      (must be < CPPAD_MAX_NUM_THREADS).
01235      Durring parallel execution, this must be the thread 
01236      that is currently executing.
01237 
01238      \return
01239      The amount of memory in bytes.
01240      */
01241      static size_t inuse(size_t thread)
01242      { 
01243           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
01244           CPPAD_ASSERT_UNKNOWN( 
01245                thread == thread_num() || (! in_parallel()) 
01246           );
01247           thread_alloc_info* info = thread_info(thread);
01248           return info->count_inuse_;
01249      }
01250 /* -----------------------------------------------------------------------
01251 $begin ta_available$$
01252 $spell
01253      num
01254      thread_alloc
01255 $$
01256 
01257 $section Amount of Memory Available for Quick Use by a Thread$$
01258 
01259 $index available, thread_alloc$$
01260 $index thread_alloc, available$$
01261 $index memory, available$$
01262 $index thread, available memory$$
01263 
01264 $head Syntax$$
01265 $icode%num_bytes% = thread_alloc::available(%thread%)%$$
01266 
01267 $head Purpose$$
01268 Memory being managed by $cref thread_alloc$$ has two states,
01269 currently in use by the specified thread,
01270 and quickly available for future use by the specified thread.
01271 This function informs the program how much memory is available.
01272 
01273 $head thread$$
01274 This argument has prototype
01275 $codei%
01276      size_t %thread%
01277 %$$
01278 Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
01279 or the current execution mode must be sequential 
01280 (not $cref/parallel/ta_in_parallel/$$).
01281 
01282 $head num_bytes$$
01283 The return value has prototype
01284 $codei%
01285      size_t %num_bytes%
01286 %$$
01287 It is the number of bytes currently available for use by the specified thread.
01288 
01289 $head Example$$
01290 $cref thread_alloc.cpp$$
01291 
01292 $end
01293 */
01294      /*!
01295      Determine the amount of memory that is currently available for use.
01296 
01297      \copydetails inuse
01298      */
01299      static size_t available(size_t thread)
01300      {
01301           CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
01302           CPPAD_ASSERT_UNKNOWN( 
01303                thread == thread_num() || (! in_parallel()) 
01304           );
01305           thread_alloc_info* info = thread_info(thread);
01306           return info->count_available_;
01307      }
01308 /* -----------------------------------------------------------------------
01309 $begin ta_create_array$$
01310 $spell
01311      inuse
01312      thread_alloc
01313      sizeof
01314 $$
01315 
01316 $section Allocate An Array and Call Default Constructor for its Elements$$
01317 
01318 $index create_array, thread_alloc$$
01319 $index thread_alloc, create_array$$
01320 $index array, allocate$$
01321 $index allocate, array$$
01322 
01323 $head Syntax$$
01324 $icode%array% = thread_alloc::create_array<%Type%>(%size_min%, %size_out%)%$$.
01325 
01326 $head Purpose$$
01327 Create a new raw array using $cref thread_alloc$$ memory allocator 
01328 (works well in a multi-threading environment)
01329 and call default constructor for each element.
01330 
01331 $head Type$$
01332 The type of the elements of the array.
01333 
01334 $head size_min$$
01335 This argument has prototype
01336 $codei%
01337      size_t %size_min%
01338 %$$
01339 This is the minimum number of elements that there can be
01340 in the resulting $icode array$$.
01341 
01342 $head size_out$$
01343 This argument has prototype
01344 $codei%
01345      size_t& %size_out%
01346 %$$
01347 The input value of this argument does not matter.
01348 Upon return, it is the actual number of elements 
01349 in $icode array$$ 
01350 ($icode% size_min %<=% size_out%$$).
01351 
01352 $head array$$
01353 The return value $icode array$$ has prototype
01354 $codei%
01355      %Type%* %array%
01356 %$$
01357 It is array with $icode size_out$$ elements.
01358 The default constructor for $icode Type$$ is used to initialize the 
01359 elements of $icode array$$.
01360 Note that $cref/delete_array/ta_delete_array/$$
01361 should be used to destroy the array when it is no longer needed.
01362 
01363 $head Delta$$
01364 The amount of memory $cref/inuse/ta_inuse/$$ by the current thread, 
01365 will increase $icode delta$$ where
01366 $codei%
01367      sizeof(%Type%) * (%size_out% + 1) > %delta% >= sizeof(%Type%) * %size_out%
01368 %$$
01369 The $cref/available/ta_available/$$ memory will decrease by $icode delta$$,
01370 (and the allocation will be faster)
01371 if a previous allocation with $icode size_min$$ between its current value
01372 and $icode size_out$$ is available. 
01373 
01374 $head Example$$
01375 $cref thread_alloc.cpp$$
01376 
01377 $end 
01378 */
01379      /*!
01380      Use thread_alloc to allocate an array, then call default construtor
01381      for each element.
01382 
01383      \tparam Type
01384      The type of the elements of the array.
01385 
01386      \param size_min [in]
01387      The minimum number of elements in the array.
01388 
01389      \param size_out [out]
01390      The actual number of elements in the array.
01391 
01392      \return
01393      pointer to the first element of the array.
01394      The default constructor is used to initialize 
01395      all the elements of the array.
01396 
01397      \par
01398      The \c extra_ field, in the \c thread_alloc node before the return value,
01399      is set to size_out.
01400      */
01401      template <class Type>
01402      static Type* create_array(size_t size_min, size_t& size_out)
01403      {    // minimum number of bytes to allocate
01404           size_t min_bytes = size_min * sizeof(Type);
01405           // do the allocation 
01406           size_t num_bytes;
01407           void*  v_ptr     = get_memory(min_bytes, num_bytes);
01408           // This is where the array starts
01409           Type*  array     = reinterpret_cast<Type*>(v_ptr);
01410           // number of Type values in the allocation
01411           size_out         = num_bytes / sizeof(Type);
01412           // store this number in the extra field
01413           block_t* node    = reinterpret_cast<block_t*>(v_ptr) - 1;
01414           node->extra_     = size_out;
01415 
01416           // call default constructor for each element
01417           size_t i;
01418           for(i = 0; i < size_out; i++)
01419                new(array + i) Type();
01420 
01421           return array;
01422      }
01423 /* -----------------------------------------------------------------------
01424 $begin ta_delete_array$$
01425 $spell
01426      inuse
01427      thread_alloc
01428      sizeof
01429      deallocate
01430 $$
01431 
01432 $section Deallocate An Array and Call Destructor for its Elements$$
01433 
01434 $index delete_array, thread_alloc$$
01435 $index thread_alloc, delete_array$$
01436 $index array, allocate$$
01437 $index allocate, array$$
01438 
01439 $head Syntax$$
01440 $codei%thread_alloc::delete_array(%array%)%$$.
01441 
01442 $head Purpose$$
01443 Returns memory corresponding to an array created by 
01444 (create by $cref/create_array/ta_create_array/$$) to the 
01445 $cref/available/ta_available/$$ memory pool for the current thread.
01446 
01447 $head Type$$
01448 The type of the elements of the array.
01449 
01450 $head array$$
01451 The argument $icode array$$ has prototype
01452 $codei%
01453      %Type%* %array%
01454 %$$
01455 It is a value returned by $cref/create_array/ta_create_array/$$ and not yet deleted.
01456 The $icode Type$$ destructor is called for each element in the array.
01457 
01458 $head Thread$$
01459 The $cref/current thread/ta_thread_num/$$ must be the
01460 same as when $cref/create_array/ta_create_array/$$ returned the value $icode array$$.
01461 There is an exception to this rule:
01462 when the current execution mode is sequential
01463 (not $cref/parallel/ta_in_parallel/$$) the current thread number does not matter.
01464 
01465 $head Delta$$
01466 The amount of memory $cref/inuse/ta_inuse/$$ will decrease by $icode delta$$,
01467 and the $cref/available/ta_available/$$ memory will increase by $icode delta$$,
01468 where $cref/delta/ta_create_array/Delta/$$ 
01469 is the same as for the corresponding call to $code create_array$$.
01470 
01471 $head Example$$
01472 $cref thread_alloc.cpp$$
01473 
01474 $end 
01475 */
01476      /*!
01477      Return Memory Used for an Array to the Available Pool
01478      (include destructor call for each element).
01479 
01480      \tparam Type
01481      The type of the elements of the array.
01482 
01483      \param array [in]
01484      A value returned by \c create_array that has not yet been deleted.
01485      The \c Type destructor is used to destroy each of the elements 
01486      of the array.
01487 
01488      \par
01489      Durring parallel execution, the current thread must be the same
01490      as during the corresponding call to \c create_array.
01491      */
01492      template <class Type>
01493      static void delete_array(Type* array)
01494      {    // determine the number of values in the array
01495           block_t* node = reinterpret_cast<block_t*>(array) - 1;
01496           size_t size     = node->extra_;
01497 
01498           // call destructor for each element
01499           size_t i;
01500           for(i = 0; i < size; i++)
01501                (array + i)->~Type();
01502 
01503           // return the memory to the available pool for this thread
01504           thread_alloc::return_memory( reinterpret_cast<void*>(array) );
01505      }
01506 /* -----------------------------------------------------------------------
01507 $begin ta_free_all$$
01508 $spell
01509      alloc
01510      bool
01511      inuse
01512 $$
01513 
01514 $section Free All Memory That Was Allocated for Use by thread_alloc$$ 
01515 
01516 $index free, all thread_alloc$$
01517 $index thread_alloc, free all$$
01518 
01519 $head Syntax$$
01520 $icode%ok% = thread_alloc::free_all()%$$.
01521 
01522 $head Purpose$$
01523 Returns all memory that was used by $code thread_alloc$$ to the system.
01524 
01525 $head ok$$
01526 The return value $icode ok$$ has prototype
01527 $codei%
01528      bool %ok%
01529 %$$
01530 Its value will be $code true$$ if all the memory can be freed.
01531 This requires that for all $icode thread$$ indices, there is no memory 
01532 $cref/inuse/ta_inuse/$$; i.e.,
01533 $codei%
01534      0 == thread_alloc::inuse(%thread%)
01535 %$$
01536 Otherwise, the return value will be false.
01537 
01538 $head Restrictions$$
01539 This function cannot be called while in parallel mode.
01540 
01541 $head Example$$
01542 $cref thread_alloc.cpp$$
01543 $end 
01544 */
01545      /*!
01546      Return to the system all thread_alloc memory that is not currently inuse.
01547 
01548      \return
01549      If no \c thread_alloc memory is currently inuse, 
01550      all memory is returned to the system and the return value is true.
01551      Otherwise the return value is false.
01552      */
01553      static bool free_all(void)
01554      {    CPPAD_ASSERT_KNOWN(
01555                ! in_parallel(),
01556                "free_all cannot be used while in parallel execution"
01557           );
01558           bool ok = true;
01559           size_t thread = CPPAD_MAX_NUM_THREADS;
01560           while(thread--)
01561           {    ok &= inuse(thread) == 0;
01562                free_available(thread);
01563           }
01564           return ok;
01565      }
01566 };
01567 
01568 
01569 } // END_CPPAD_NAMESPACE
01570 
01571 // preprocessor symbols local to this file
01572 # undef CPPAD_MAX_NUM_CAPACITY
01573 # undef CPPAD_MIN_DOUBLE_CAPACITY
01574 # undef CPPAD_TRACE_CAPACITY
01575 # undef CPPAD_TRACE_THREAD
01576 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines