AstSharedMemoryParallelProcessingImpl.h

Go to the documentation of this file.
00001 // Author: Gergo Barany
00002 // $Id: AstSharedMemoryParallelProcessing.C,v 1.1 2008/01/08 02:56:38 dquinlan Exp $
00003 
00004 #ifndef ASTSHAREDMEMORYPARALLELPROCESSING_C
00005 #define ASTSHAREDMEMORYPARALLELPROCESSING_C
00006 
00007 // tps (01/08/2010) Added sage3basic since this doesnt compile under gcc4.1.2
00008 //#include "sage3basic.h"
00009 //#include "sage3.h"
00010 
00011 // DQ (3/20/2009): Trying to fix error on Cygwin platform.
00012 #ifdef _MSC_VER
00013 #pragma message ("Error: pthread.h is unavailable on MSVC, we might want to use boost.thread library.")
00014 #else
00015 #include <pthread.h>
00016 #endif
00017 
00018 #include "AstSharedMemoryParallelProcessing.h"
00019 
00020 // Throughout this file, I is the InheritedAttributeType, S is the
00021 // SynthesizedAttributeType -- the type names are still horrible
00022 
00023 // parallel TOP DOWN BOTTOM UP implementation
00024 
00025 template <class I, class S>
00026 AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::
00027 AstSharedMemoryParallelizableTopDownBottomUpProcessing(
00028         const AstSharedMemoryParallelProcessingSynchronizationInfo &syncInfo,
00029         const typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::TraversalPtrList &t)
00030     : AstCombinedTopDownBottomUpProcessing<I, S>(t),
00031       AstSharedMemoryParallelProcessingSynchronizationBase(syncInfo),
00032       visitedNodes(0), runningParallelTraversal(false),
00033       synchronizationWindowSize(syncInfo.synchronizationWindowSize)
00034 {
00035 }
00036 
00037 template <class I, class S>
00038 void 
00039 AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::set_runningParallelTraversal(bool val)
00040 {
00041     runningParallelTraversal = val;
00042 }
00043 
00044 template <class I, class S>
00045 typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList *
00046 AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::
00047 evaluateInheritedAttribute(SgNode *astNode,
00048         typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList *inheritedValues)
00049 {
00050     if (runningParallelTraversal && ++visitedNodes > synchronizationWindowSize)
00051     {
00052         synchronize();
00053         visitedNodes = 0;
00054     }
00055 
00056     // let the superclass handle actual attribute evaluation
00057     return Superclass::evaluateInheritedAttribute(astNode, inheritedValues);
00058 }
00059 
00060 template <class I, class S>
00061 void AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::
00062 atTraversalEnd()
00063 {
00064     // delegate the call to the superclass
00065     Superclass::atTraversalEnd();
00066 
00067     // signal that we are done
00068     if (runningParallelTraversal)
00069     {
00070         signalFinish();
00071         // clear the flag so subsequent traversals can be non-parallel
00072         runningParallelTraversal = false;
00073     }
00074 }
00075 
00076 // This class holds the arguments to a traversal thread: The parallelizable
00077 // traversal class that contains a number of traversals, the node to start the
00078 // traversal from, and the list of initial inherited values.
00079 template <class I, class S>
00080 struct AstSharedMemoryParallelTopDownBottomUpThreadArgs
00081 {
00082     AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S> *traversal;
00083     SgNode *basenode;
00084     typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList *inheritedValues;
00085 
00086     AstSharedMemoryParallelTopDownBottomUpThreadArgs(
00087             AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S> *traversal,
00088             SgNode *basenode,
00089             typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList *inheritedValues)
00090         : traversal(traversal), basenode(basenode), inheritedValues(inheritedValues)
00091     {
00092     }
00093 };
00094 
00095 // This is the function that is executed in each thread. It basically unpacks
00096 // its arguments and starts the traversal on them; the traversal's final
00097 // result is returned. Synchronization is built into the parallelizable
00098 // processing classes.
00099 template <class I, class S>
00100 void *parallelTopDownBottomUpProcessingThread(void *p)
00101 {
00102     AstSharedMemoryParallelTopDownBottomUpThreadArgs<I, S> *threadArgs = (AstSharedMemoryParallelTopDownBottomUpThreadArgs<I, S> *) p;
00103 
00104     AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S> *traversal = threadArgs->traversal;
00105     SgNode *basenode = threadArgs->basenode;
00106     typename AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList
00107         *inheritedValues = threadArgs->inheritedValues;
00108     delete threadArgs;
00109 
00110     // Set the flag that indicates that this is indeed a parallel traversal;
00111     // it is cleared by the traversal class itself when it is done.
00112     traversal->set_runningParallelTraversal(true);
00113     // Start the traversal.
00114     return traversal->traverse(basenode, inheritedValues);
00115 }
00116 
00117 template <class I, class S>
00118 typename AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::SynthesizedAttributeTypeList *
00119 AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::traverseInParallel(
00120         SgNode *basenode,
00121         typename AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::InheritedAttributeTypeList *inheritedValues)
00122 {
00123  // GB (09/27/2007): Is this really required? Inheritance of templated classes is just weird.
00124     const typename Superclass::TraversalPtrList &traversals = Superclass::traversals;
00125 
00126     size_t numberOfTraversals = traversals.size();
00127     size_t i;
00128 
00129     AstSharedMemoryParallelProcessingSynchronizationInfo syncInfo(numberOfThreads, synchronizationWindowSize);
00130 
00131     // Chop the flat list of traversals apart and distribute them into a few
00132     // parallelizable traversals.
00133     ParallelizableTraversalPtrList parallelTraversals(numberOfThreads);
00134     std::vector<InheritedAttributeTypeList *> parallelInheritedValues(numberOfThreads);
00135     size_t begin = 0, end;
00136     for (i = 0; i < numberOfThreads; i++)
00137     {
00138         end = begin + numberOfTraversals / numberOfThreads;
00139         if (end > numberOfTraversals)
00140             end = numberOfTraversals;
00141 
00142         parallelTraversals[i]
00143             = new AstSharedMemoryParallelizableTopDownBottomUpProcessing<I, S>(syncInfo,
00144                     std::vector<TraversalPtr>(traversals.begin() + begin, traversals.begin() + end));
00145         parallelInheritedValues[i]
00146             = new InheritedAttributeTypeList(
00147                         inheritedValues->begin() + begin, inheritedValues->begin() + end);
00148         begin = end;
00149     }
00150 
00151 #ifndef _MSC_VER
00152     // Start a thread for each of the parallelizable traversals with its share
00153     // of the initial inherited attributes.
00154     pthread_t *threads = new pthread_t[numberOfThreads];
00155     for (i = 0; i < numberOfThreads; i++)
00156     {
00157         pthread_create(&threads[i], NULL,
00158                 parallelTopDownBottomUpProcessingThread<I, S>,
00159                 new AstSharedMemoryParallelTopDownBottomUpThreadArgs<I, S>(
00160                     parallelTraversals[i], basenode, parallelInheritedValues[i]));
00161     }
00162 
00163     // Main "event loop" for the "master" thread: Simply wait for the
00164     // condition that is signalled when a thread is completely done with its
00165     // traversal. The counter tells us when we are finished.
00166     pthread_mutex_lock(syncInfo.mutex);
00167     while (*syncInfo.finishedThreads < numberOfThreads)
00168         pthread_cond_wait(syncInfo.threadFinishedEvent, syncInfo.mutex);
00169     pthread_mutex_unlock(syncInfo.mutex);
00170 
00171     // Grab the results from each traversal.
00172     std::vector<SynthesizedAttributeTypeList *> finalResults(numberOfThreads);
00173     for (i = 0; i < numberOfThreads; i++)
00174         pthread_join(threads[i], (void **) &finalResults[i]);
00175     delete threads;
00176 #endif
00177 
00178     // Flatten the nested list of traversal results.
00179     SynthesizedAttributeTypeList *flatFinalResults = new SynthesizedAttributeTypeList;
00180     for (i = 0; i < numberOfThreads; i++)
00181         std::copy(finalResults[i]->begin(), finalResults[i]->end(), std::back_inserter(*flatFinalResults));
00182 
00183     // Done! Return the final results.
00184     return flatFinalResults;
00185 }
00186 
00187 template <class I, class S>
00188 AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::AstSharedMemoryParallelTopDownBottomUpProcessing()
00189   : numberOfThreads(2), synchronizationWindowSize(100000)
00190 {
00191 }
00192 
00193 template <class I, class S>
00194 AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::
00195 AstSharedMemoryParallelTopDownBottomUpProcessing(const AstSharedMemoryParallelTopDownBottomUpProcessing<I,S>::TraversalPtrList &traversals)
00196   : AstCombinedTopDownBottomUpProcessing<I, S>(traversals), numberOfThreads(2), synchronizationWindowSize(100000)
00197 {
00198 }
00199 
00200 template <class I, class S>
00201 void
00202 AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::set_numberOfThreads(size_t threads) const
00203 {
00204 #if !USE_ROSE
00205 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00206 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00207 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00208     numberOfThreads = threads;
00209 #endif
00210 }
00211 
00212 template <class I, class S>
00213 void
00214 AstSharedMemoryParallelTopDownBottomUpProcessing<I, S>::set_synchronizationWindowSize(size_t windowSize) const
00215 {
00216 #if !USE_ROSE
00217 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00218 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00219 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00220     synchronizationWindowSize = windowSize;
00221 #endif
00222 }
00223 
00224 // parallel TOP DOWN implementation
00225 
00226 template <class I>
00227 AstSharedMemoryParallelizableTopDownProcessing<I>::
00228 AstSharedMemoryParallelizableTopDownProcessing(
00229         const AstSharedMemoryParallelProcessingSynchronizationInfo &syncInfo,
00230         const typename AstSharedMemoryParallelizableTopDownProcessing<I>::TraversalPtrList &t)
00231     : AstCombinedTopDownProcessing<I>(t),
00232       AstSharedMemoryParallelProcessingSynchronizationBase(syncInfo),
00233       visitedNodes(0), runningParallelTraversal(false),
00234       synchronizationWindowSize(syncInfo.synchronizationWindowSize)
00235 {
00236 }
00237 
00238 template <class I>
00239 void 
00240 AstSharedMemoryParallelizableTopDownProcessing<I>::set_runningParallelTraversal(bool val)
00241 {
00242     runningParallelTraversal = val;
00243 }
00244 
00245 template <class I>
00246 typename AstSharedMemoryParallelizableTopDownProcessing<I>::InheritedAttributeTypeList *
00247 AstSharedMemoryParallelizableTopDownProcessing<I>::
00248 evaluateInheritedAttribute(SgNode *astNode,
00249         typename AstSharedMemoryParallelizableTopDownProcessing<I>::InheritedAttributeTypeList *inheritedValues)
00250 {
00251     if (runningParallelTraversal && ++visitedNodes > synchronizationWindowSize)
00252     {
00253         synchronize();
00254         visitedNodes = 0;
00255     }
00256 
00257     // let the superclass handle actual attribute evaluation
00258     return Superclass::evaluateInheritedAttribute(astNode, inheritedValues);
00259 }
00260 
00261 template <class I>
00262 void AstSharedMemoryParallelizableTopDownProcessing<I>::
00263 atTraversalEnd()
00264 {
00265     // delegate the call to the superclass
00266     Superclass::atTraversalEnd();
00267 
00268     // signal that we are done
00269     if (runningParallelTraversal)
00270     {
00271         signalFinish();
00272         // clear the flag so subsequent traversals can be non-parallel
00273         runningParallelTraversal = false;
00274     }
00275 }
00276 
00277 // This class holds the arguments to a traversal thread: The parallelizable
00278 // traversal class that contains a number of traversals, the node to start the
00279 // traversal from, and the list of initial inherited values.
00280 template <class I>
00281 struct AstSharedMemoryParallelTopDownThreadArgs
00282 {
00283     AstSharedMemoryParallelizableTopDownProcessing<I> *traversal;
00284     SgNode *basenode;
00285     typename AstSharedMemoryParallelizableTopDownProcessing<I>::InheritedAttributeTypeList *inheritedValues;
00286 
00287     AstSharedMemoryParallelTopDownThreadArgs(
00288             AstSharedMemoryParallelizableTopDownProcessing<I> *traversal,
00289             SgNode *basenode,
00290             typename AstSharedMemoryParallelizableTopDownProcessing<I>::InheritedAttributeTypeList *inheritedValues)
00291         : traversal(traversal), basenode(basenode), inheritedValues(inheritedValues)
00292     {
00293     }
00294 };
00295 
00296 // This is the function that is executed in each thread. It basically unpacks
00297 // its arguments and starts the traversal on them; the traversal's final
00298 // result is returned. Synchronization is built into the parallelizable
00299 // processing classes.
00300 template <class I>
00301 void *parallelTopDownProcessingThread(void *p)
00302 {
00303     AstSharedMemoryParallelTopDownThreadArgs<I> *threadArgs = (AstSharedMemoryParallelTopDownThreadArgs<I> *) p;
00304 
00305     AstSharedMemoryParallelizableTopDownProcessing<I> *traversal = threadArgs->traversal;
00306     SgNode *basenode = threadArgs->basenode;
00307     typename AstSharedMemoryParallelizableTopDownProcessing<I>::InheritedAttributeTypeList
00308         *inheritedValues = threadArgs->inheritedValues;
00309     delete threadArgs;
00310 
00311     // Set the flag that indicates that this is indeed a parallel traversal;
00312     // it is cleared by the traversal class itself when it is done.
00313     traversal->set_runningParallelTraversal(true);
00314     // Start the traversal.
00315     traversal->traverse(basenode, inheritedValues);
00316 
00317     // Need to return something.
00318     return NULL;
00319 }
00320 
00321 template <class I>
00322 void
00323 AstSharedMemoryParallelTopDownProcessing<I>::traverseInParallel(
00324         SgNode *basenode,
00325         typename AstSharedMemoryParallelTopDownProcessing<I>::InheritedAttributeTypeList *inheritedValues)
00326 {
00327     const typename Superclass::TraversalPtrList &traversals = Superclass::traversals;
00328 
00329     size_t numberOfTraversals = traversals.size();
00330     size_t i;
00331 
00332     AstSharedMemoryParallelProcessingSynchronizationInfo syncInfo(numberOfThreads, synchronizationWindowSize);
00333 
00334     // Chop the flat list of traversals apart and distribute them into a few
00335     // parallelizable traversals.
00336     ParallelizableTraversalPtrList parallelTraversals(numberOfThreads);
00337     std::vector<InheritedAttributeTypeList *> parallelInheritedValues(numberOfThreads);
00338     size_t begin = 0, end;
00339     for (i = 0; i < numberOfThreads; i++)
00340     {
00341         end = begin + numberOfTraversals / numberOfThreads;
00342         if (end > numberOfTraversals)
00343             end = numberOfTraversals;
00344 
00345         parallelTraversals[i]
00346             = new AstSharedMemoryParallelizableTopDownProcessing<I>(syncInfo,
00347                     std::vector<TraversalPtr>(traversals.begin() + begin, traversals.begin() + end));
00348         parallelInheritedValues[i]
00349             = new InheritedAttributeTypeList(
00350                         inheritedValues->begin() + begin, inheritedValues->begin() + end);
00351         begin = end;
00352     }
00353 
00354     // Start a thread for each of the parallelizable traversals with its share
00355     // of the initial inherited attributes.
00356     pthread_t *threads = new pthread_t[numberOfThreads];
00357     for (i = 0; i < numberOfThreads; i++)
00358     {
00359         pthread_create(&threads[i], NULL,
00360                 parallelTopDownProcessingThread<I>,
00361                 new AstSharedMemoryParallelTopDownThreadArgs<I>(
00362                     parallelTraversals[i], basenode, parallelInheritedValues[i]));
00363     }
00364 
00365     // Main "event loop" for the "master" thread: Simply wait for the
00366     // condition that is signalled when a thread is completely done with its
00367     // traversal. The counter tells us when we are finished.
00368     pthread_mutex_lock(syncInfo.mutex);
00369     while (*syncInfo.finishedThreads < numberOfThreads)
00370         pthread_cond_wait(syncInfo.threadFinishedEvent, syncInfo.mutex);
00371     pthread_mutex_unlock(syncInfo.mutex);
00372 
00373     // Grab the results from each traversal.
00374     std::vector<void *> finalResults(numberOfThreads);
00375     for (i = 0; i < numberOfThreads; i++)
00376         pthread_join(threads[i], &finalResults[i]);
00377     delete threads;
00378 
00379     // Done!
00380 }
00381 
00382 template <class I>
00383 AstSharedMemoryParallelTopDownProcessing<I>::AstSharedMemoryParallelTopDownProcessing()
00384   : numberOfThreads(2), synchronizationWindowSize(100000)
00385 {
00386 }
00387 
00388 template <class I>
00389 AstSharedMemoryParallelTopDownProcessing<I>::
00390 AstSharedMemoryParallelTopDownProcessing(const AstSharedMemoryParallelTopDownProcessing<I>::TraversalPtrList &traversals)
00391   : AstCombinedTopDownProcessing<I>(traversals), numberOfThreads(2), synchronizationWindowSize(100000)
00392 {
00393 }
00394 
00395 template <class I>
00396 void
00397 AstSharedMemoryParallelTopDownProcessing<I>::set_numberOfThreads(size_t threads) const
00398 {
00399 #if !USE_ROSE
00400 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00401 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00402 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00403     numberOfThreads = threads;
00404 #endif
00405 }
00406 
00407 template <class I>
00408 void
00409 AstSharedMemoryParallelTopDownProcessing<I>::set_synchronizationWindowSize(size_t windowSize) const
00410 {
00411 #if !USE_ROSE
00412 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00413 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00414 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00415     synchronizationWindowSize = windowSize;
00416 #endif
00417 }
00418 
00419 // parallel BOTTOM UP implementation
00420 
00421 template <class S>
00422 AstSharedMemoryParallelizableBottomUpProcessing<S>::
00423 AstSharedMemoryParallelizableBottomUpProcessing(
00424         const AstSharedMemoryParallelProcessingSynchronizationInfo &syncInfo,
00425         const typename AstSharedMemoryParallelizableBottomUpProcessing<S>::TraversalPtrList &t)
00426     : AstCombinedBottomUpProcessing<S>(t),
00427       AstSharedMemoryParallelProcessingSynchronizationBase(syncInfo),
00428       visitedNodes(0), runningParallelTraversal(false),
00429       synchronizationWindowSize(syncInfo.synchronizationWindowSize)
00430 {
00431 }
00432 
00433 template <class S>
00434 void 
00435 AstSharedMemoryParallelizableBottomUpProcessing<S>::set_runningParallelTraversal(bool val)
00436 {
00437     runningParallelTraversal = val;
00438 }
00439 
00440 template <class S>
00441 typename AstSharedMemoryParallelizableBottomUpProcessing<S>::SynthesizedAttributeTypeList *
00442 AstSharedMemoryParallelizableBottomUpProcessing<S>::
00443 evaluateSynthesizedAttribute(SgNode *astNode,
00444         typename AstSharedMemoryParallelizableBottomUpProcessing<S>::SynthesizedAttributesList synthesizedAttributes)
00445 {
00446     if (runningParallelTraversal && ++visitedNodes > synchronizationWindowSize)
00447     {
00448         synchronize();
00449         visitedNodes = 0;
00450     }
00451 
00452     // let the superclass handle actual attribute evaluation
00453     return Superclass::evaluateSynthesizedAttribute(astNode, synthesizedAttributes);
00454 }
00455 
00456 template <class S>
00457 void AstSharedMemoryParallelizableBottomUpProcessing<S>::
00458 atTraversalEnd()
00459 {
00460     // delegate the call to the superclass
00461     Superclass::atTraversalEnd();
00462 
00463     // signal that we are done
00464     if (runningParallelTraversal)
00465     {
00466         signalFinish();
00467         // clear the flag so subsequent traversals can be non-parallel
00468         runningParallelTraversal = false;
00469     }
00470 }
00471 
00472 // This class holds the arguments to a traversal thread: The parallelizable
00473 // traversal class that contains a number of traversals, and the node to start the
00474 // traversal from.
00475 template <class S>
00476 struct AstSharedMemoryParallelBottomUpThreadArgs
00477 {
00478     AstSharedMemoryParallelizableBottomUpProcessing<S> *traversal;
00479     SgNode *basenode;
00480 
00481     AstSharedMemoryParallelBottomUpThreadArgs(
00482             AstSharedMemoryParallelizableBottomUpProcessing<S> *traversal,
00483             SgNode *basenode)
00484         : traversal(traversal), basenode(basenode)
00485     {
00486     }
00487 };
00488 
00489 // This is the function that is executed in each thread. It basically unpacks
00490 // its arguments and starts the traversal on them; the traversal's final
00491 // result is returned. Synchronization is built into the parallelizable
00492 // processing classes.
00493 template <class S>
00494 void *parallelBottomUpProcessingThread(void *p)
00495 {
00496     AstSharedMemoryParallelBottomUpThreadArgs<S> *threadArgs = (AstSharedMemoryParallelBottomUpThreadArgs<S> *) p;
00497 
00498     AstSharedMemoryParallelizableBottomUpProcessing<S> *traversal = threadArgs->traversal;
00499     SgNode *basenode = threadArgs->basenode;
00500     delete threadArgs;
00501 
00502     // Set the flag that indicates that this is indeed a parallel traversal;
00503     // it is cleared by the traversal class itself when it is done.
00504     traversal->set_runningParallelTraversal(true);
00505     // Start the traversal.
00506     return traversal->traverse(basenode);
00507 }
00508 
00509 template <class S>
00510 typename AstSharedMemoryParallelBottomUpProcessing<S>::SynthesizedAttributeTypeList *
00511 AstSharedMemoryParallelBottomUpProcessing<S>::traverseInParallel(SgNode *basenode)
00512 {
00513     const typename Superclass::TraversalPtrList &traversals = Superclass::traversals;
00514 
00515     size_t numberOfTraversals = traversals.size();
00516     size_t i;
00517 
00518     AstSharedMemoryParallelProcessingSynchronizationInfo syncInfo(numberOfThreads, synchronizationWindowSize);
00519 
00520     // Chop the flat list of traversals apart and distribute them into a few
00521     // parallelizable traversals.
00522     ParallelizableTraversalPtrList parallelTraversals(numberOfThreads);
00523     size_t begin = 0, end;
00524     for (i = 0; i < numberOfThreads; i++)
00525     {
00526         end = begin + numberOfTraversals / numberOfThreads;
00527         if (end > numberOfTraversals)
00528             end = numberOfTraversals;
00529 
00530         parallelTraversals[i]
00531             = new AstSharedMemoryParallelizableBottomUpProcessing<S>(syncInfo,
00532                     std::vector<TraversalPtr>(traversals.begin() + begin, traversals.begin() + end));
00533         begin = end;
00534     }
00535 
00536     // Start a thread for each of the parallelizable traversals.
00537     pthread_t *threads = new pthread_t[numberOfThreads];
00538     for (i = 0; i < numberOfThreads; i++)
00539     {
00540         pthread_create(&threads[i], NULL,
00541                 parallelBottomUpProcessingThread<S>,
00542                 new AstSharedMemoryParallelBottomUpThreadArgs<S>(
00543                     parallelTraversals[i], basenode));
00544     }
00545 
00546     // Main "event loop" for the "master" thread: Simply wait for the
00547     // condition that is signalled when a thread is completely done with its
00548     // traversal. The counter tells us when we are finished.
00549     pthread_mutex_lock(syncInfo.mutex);
00550     while (*syncInfo.finishedThreads < numberOfThreads)
00551         pthread_cond_wait(syncInfo.threadFinishedEvent, syncInfo.mutex);
00552     pthread_mutex_unlock(syncInfo.mutex);
00553 
00554     // Grab the results from each traversal.
00555     std::vector<SynthesizedAttributeTypeList *> finalResults(numberOfThreads);
00556     for (i = 0; i < numberOfThreads; i++)
00557         pthread_join(threads[i], (void **) &finalResults[i]);
00558     delete threads;
00559 
00560     // Flatten the nested list of traversal results.
00561     SynthesizedAttributeTypeList *flatFinalResults = new SynthesizedAttributeTypeList;
00562     for (i = 0; i < numberOfThreads; i++)
00563         std::copy(finalResults[i]->begin(), finalResults[i]->end(), std::back_inserter(*flatFinalResults));
00564 
00565     // Done! Return the final results.
00566     return flatFinalResults;
00567 }
00568 
00569 template <class S>
00570 AstSharedMemoryParallelBottomUpProcessing<S>::AstSharedMemoryParallelBottomUpProcessing()
00571   : numberOfThreads(2), synchronizationWindowSize(100000)
00572 {
00573 }
00574 
00575 template <class S>
00576 AstSharedMemoryParallelBottomUpProcessing<S>::
00577 AstSharedMemoryParallelBottomUpProcessing(const AstSharedMemoryParallelBottomUpProcessing<S>::TraversalPtrList &traversals)
00578   : AstCombinedBottomUpProcessing<S>(traversals), numberOfThreads(2), synchronizationWindowSize(100000)
00579 {
00580 }
00581 
00582 template <class S>
00583 void
00584 AstSharedMemoryParallelBottomUpProcessing<S>::set_numberOfThreads(size_t threads) const
00585 {
00586 #if !USE_ROSE
00587 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00588 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00589 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00590     numberOfThreads = threads;
00591 #endif
00592 }
00593 
00594 template <class S>
00595 void
00596 AstSharedMemoryParallelBottomUpProcessing<S>::set_synchronizationWindowSize(size_t windowSize) const
00597 {
00598 #if !USE_ROSE
00599 // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct
00600 // since it is a private variable.  But since we are only trying to compile ROSE with ROSE (using the
00601 // new EDG 4.3 front-end as a tests) we can just skip this case for now.
00602     synchronizationWindowSize = windowSize;
00603 #endif
00604 }
00605 
00606 #endif

Generated on Tue Jan 31 05:31:20 2012 for ROSE by  doxygen 1.4.7