"Fossies" - the Fresh Open Source Software Archive

Member "Hoard-3.13/src/source/mactls.cpp" (2 Jan 2019, 5013 Bytes) of package /linux/misc/Hoard-3.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mactls.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.12_vs_3.13.

    1 /*
    2   The Hoard Multiprocessor Memory Allocator
    3   www.hoard.org
    4 
    5   Author: Emery Berger, http://www.emeryberger.org
    6  
    7   Copyright (c) 1998-2019 Emery Berger
    8 
    9   This program is free software; you can redistribute it and/or modify
   10   it under the terms of the GNU General Public License as published by
   11   the Free Software Foundation; either version 2 of the License, or
   12   (at your option) any later version.
   13   
   14   This program is distributed in the hope that it will be useful,
   15   but WITHOUT ANY WARRANTY; without even the implied warranty of
   16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17   GNU General Public License for more details.
   18   
   19   You should have received a copy of the GNU General Public License
   20   along with this program; if not, write to the Free Software
   21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22 
   23 */
   24 
   25 #if !defined(__APPLE__)
   26 #error "This file is intended for use with MacOS systems only."
   27 #endif
   28 
   29 #include <dlfcn.h>
   30 #include <pthread.h>
   31 #include <utility>
   32 
   33 #include "Heap-Layers/heaplayers.h"
   34 #include "hoard/hoardtlab.h"
   35 
   36 extern Hoard::HoardHeapType * getMainHoardHeap();
   37 
   38 static pthread_key_t theHeapKey;
   39 static pthread_once_t key_once = PTHREAD_ONCE_INIT;
   40 
   41 // Called when the thread goes away.  This function clears out the
   42 // TLAB and then reclaims the memory allocated to hold it.
   43 
   44 static void deleteThatHeap(void * p) {
   45   reinterpret_cast<TheCustomHeapType *>(p)->clear();
   46   getMainHoardHeap()->free(p);
   47 
   48   // Relinquish the assigned heap.
   49   getMainHoardHeap()->releaseHeap();
   50 }
   51 
   52 static void make_heap_key() {
   53   if (pthread_key_create(&theHeapKey, deleteThatHeap) != 0) {
   54     // This should never happen.
   55   }
   56 }
   57 
   58 static bool initializedTSD = false;
   59 
   60 static bool initTSD() {
   61   if (!initializedTSD) {
   62     // Ensure that the key is initialized -- once.
   63     pthread_once(&key_once, make_heap_key);
   64     initializedTSD = true;
   65   }
   66   return true;
   67 }
   68 
   69 bool isCustomHeapInitialized() {
   70   return initializedTSD;
   71 }
   72 
   73 static TheCustomHeapType * initializeCustomHeap() {
   74   TheCustomHeapType * heap =
   75     reinterpret_cast<TheCustomHeapType *>(pthread_getspecific(theHeapKey));
   76   if (heap == NULL) {
   77     // Defensive programming in case this is called twice.
   78     // Allocate a per-thread heap.
   79     size_t sz = sizeof(TheCustomHeapType);
   80     char * mh = reinterpret_cast<char *>(getMainHoardHeap()->malloc(sz));
   81     heap = new (mh) TheCustomHeapType(getMainHoardHeap());
   82     // Store it in the appropriate thread-local area.
   83     pthread_setspecific(theHeapKey, heap);
   84   }
   85   return heap;
   86 }
   87 
   88 TheCustomHeapType * getCustomHeap() {
   89   initTSD();
   90   // Allocate a per-thread heap.
   91   TheCustomHeapType * heap =
   92     reinterpret_cast<TheCustomHeapType *>(pthread_getspecific(theHeapKey));
   93   if (heap == NULL)  {
   94     heap = initializeCustomHeap();
   95   }
   96   return heap;
   97 }
   98 
   99 
  100 //
  101 // Intercept thread creation and destruction to flush the TLABs.
  102 //
  103 
  104 
  105 extern "C" {
  106   typedef void * (*threadFunctionType)(void * arg);
  107 }
  108 
  109 // A special routine we call on thread exits to free up some resources.
  110 static void exitRoutine() {
  111   TheCustomHeapType * heap = getCustomHeap();
  112 
  113   // Clear the TLAB's buffer.
  114   heap->clear();
  115 
  116   // Relinquish the assigned heap.
  117   getMainHoardHeap()->releaseHeap();
  118 }
  119 
  120 extern "C" {
  121   static inline void * startMeUp(void * a) {
  122     // Make sure that the custom heap has been initialized,
  123     // then find an unused process heap for this thread, if possible.
  124     getCustomHeap();
  125     getMainHoardHeap()->findUnusedHeap();
  126 
  127     // Extract the pair elements (function, argument).
  128     pair<threadFunctionType, void *> * z
  129       = reinterpret_cast<pair<threadFunctionType, void *> *>(a);
  130 
  131     threadFunctionType fun = z->first;
  132     void * arg = z->second;
  133 
  134     // Execute the function.
  135     void * result = (*fun)(arg);
  136 
  137     // We're done: free up resources.
  138     exitRoutine();
  139     getCustomHeap()->free(a);
  140     return result;
  141   }
  142 }
  143 
  144 
  145 extern volatile bool anyThreadCreated;
  146 
  147 
  148 // Intercept thread creation. We need this to first associate
  149 // a heap with the thread and instantiate the thread-specific heap
  150 // (TLAB).  When the thread ends, we relinquish the assigned heap and
  151 // free up the TLAB.
  152 
  153 
  154 extern "C" void xxpthread_exit(void * value_ptr) {
  155   // Do necessary clean-up of the TLAB and get out.
  156   exitRoutine();
  157   pthread_exit(value_ptr);
  158 }
  159 
  160 extern "C" int xxpthread_create(pthread_t *thread,
  161                                 const pthread_attr_t *attr,
  162                                 void * (*start_routine)(void *),
  163                                 void * arg) {
  164   // Force initialization of the TLAB before our first thread is created.
  165   static TheCustomHeapType * t = getCustomHeap();
  166 
  167   anyThreadCreated = true;
  168 
  169   pair<threadFunctionType, void *> * args =
  170     new (t->malloc(sizeof(pair<threadFunctionType, void *>)))
  171     pair<threadFunctionType, void *>(start_routine, arg);
  172 
  173   int result = pthread_create(thread, attr, startMeUp, args);
  174   return result;
  175 }
  176 
  177 
  178 MAC_INTERPOSE(xxpthread_create, pthread_create);
  179 MAC_INTERPOSE(xxpthread_exit, pthread_exit);
  180 
  181 
  182