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