diff options
Diffstat (limited to 'docs/tutorials/017')
-rw-r--r-- | docs/tutorials/017/017.dsp | 108 | ||||
-rw-r--r-- | docs/tutorials/017/Barrier_i.cpp | 160 | ||||
-rw-r--r-- | docs/tutorials/017/Barrier_i.h | 67 | ||||
-rw-r--r-- | docs/tutorials/017/Makefile | 77 | ||||
-rw-r--r-- | docs/tutorials/017/barrier.cpp | 166 | ||||
-rw-r--r-- | docs/tutorials/017/barrier2.cpp | 178 | ||||
-rw-r--r-- | docs/tutorials/017/combine.shar | 380 | ||||
-rw-r--r-- | docs/tutorials/017/page01.html | 52 | ||||
-rw-r--r-- | docs/tutorials/017/page02.html | 195 | ||||
-rw-r--r-- | docs/tutorials/017/page03.html | 100 | ||||
-rw-r--r-- | docs/tutorials/017/page04.html | 188 | ||||
-rw-r--r-- | docs/tutorials/017/page05.html | 32 | ||||
-rw-r--r-- | docs/tutorials/017/page06.html | 206 |
13 files changed, 0 insertions, 1909 deletions
diff --git a/docs/tutorials/017/017.dsp b/docs/tutorials/017/017.dsp deleted file mode 100644 index 932599a7a46..00000000000 --- a/docs/tutorials/017/017.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="017" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=017 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "017.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "017.mak" CFG="017 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "017 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "017 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "017 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "017 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"barrier.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "017 - Win32 Release"
-# Name "017 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\barrier.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Barrier_i.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Barrier_i.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/017/Barrier_i.cpp b/docs/tutorials/017/Barrier_i.cpp deleted file mode 100644 index 0784205360a..00000000000 --- a/docs/tutorials/017/Barrier_i.cpp +++ /dev/null @@ -1,160 +0,0 @@ - -// $Id$ - -#include "Barrier_i.h" - -/* Initialize the threads_ count to zero and the barrier_ pointer to a - safe value. At the same time, we remember the thread that created - us so that we can allow it to change the thread count. -*/ -Barrier::Barrier(void) - : threads_(0) - ,barrier_(0) - ,new_barrier_(0) -{ - owner_ = ACE_OS::thr_self(); -} - -/* Ensure that barrier_ get's deleted so that we don't have a memory leak. - */ -Barrier::~Barrier(void) -{ - delete barrier_; -} - -void Barrier::owner( ACE_thread_t _owner ) -{ - owner_ = _owner; -} - -// Report on the number of threads. -u_int Barrier::threads(void) -{ - return threads_.value(); -} - -/* Allow the owning thread to (re)set the number of threads. - make_barrier() is called because it will wait() if we were already - configured. Typical usage would be for the worker threads to - wait() while the primary (eg -- owner) thread adjusts the thread - count. - - For instance: - In the worker threads: - if( myBarrier.threads() != current_thread_count ) - myBarrier.wait(); - - In the primary thread: - if( myBarrier.threads() != current_thread_count ) - myBarrier.threads( current_thread_count, 1 ); - */ -int Barrier::threads( u_int _threads, int _wait ) -{ - if( ! ACE_OS::thr_equal(ACE_OS::thr_self(), owner_) ) - { - return -1; - } - - threads_ = _threads; - - return make_barrier(_wait); -} - -/* Wait for all threads to synch if the thread count is valid. Note - that barrier_ will be 0 if the threads() mutator has not been - invoked. -*/ -int Barrier::wait(void) -{ - if( ! barrier_ ) - { - return -1; - } - - // If the threads() mutator has been used, new_barrier_ will - // point to a new ACE_Barrier instance. We'll use a - // traditional double-check here to move that new object into - // place and cleanup the old one. - if( new_barrier_ ) - { - // mutex so that only one thread can do this part. - ACE_Guard<ACE_Mutex> mutex(barrier_mutex_); - - // We only want the first thread to plug in the new barrier... - if( new_barrier_ ) - { - // out with the old and in with the new. - delete barrier_; - barrier_ = new_barrier_; - new_barrier_ = 0; - } - } - - return barrier_->wait(); -} - -/* Wait for all threads to synch. As each thread passes wait(), it - will decrement our thread counter. (That is why we had to make - threads_ an atomic op.) When the last thread decrements the - counter it will also delete the ACE_Barrier & free up a little - memory. -*/ -int Barrier::done(void) -{ - if( this->wait() == -1 ) - { - return -1; - } - - --threads_; - - if( ! threads_.value() ) - { - delete barrier_; - barrier_ = 0; - } - - return 0; -} - -/* This will build the actual barrier. I broke this code out of the - threads() mutator in case it might be useful elsewhere. - If a barrier already exists, we will wait for all threads before - creating a new one. This trait is what allows the threads mutator - to be used as shown above. - */ -int Barrier::make_barrier( int _wait ) -{ - // Ensure we have a valid thread count. - if( ! threads_.value() ) - { - return -1; - } - - // If a barrier already exists, we'll arrange for it to be - // replaced through the wait() method above. - if( barrier_ ) - { - // Create the new barrier that wait() will install for us. - ACE_NEW_RETURN(new_barrier_,ACE_Barrier(threads_.value()),-1); - - // Wait for our siblings to synch before continuing - if( _wait ) - { - barrier_->wait(); - } - } - else - { - // Create the initial barrier. - ACE_NEW_RETURN(barrier_,ACE_Barrier(threads_.value()),-1); - } - - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Atomic_Op <ACE_Mutex, u_int>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Atomic_Op <ACE_Mutex, u_int> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/docs/tutorials/017/Barrier_i.h b/docs/tutorials/017/Barrier_i.h deleted file mode 100644 index cb9c3d4ce0e..00000000000 --- a/docs/tutorials/017/Barrier_i.h +++ /dev/null @@ -1,67 +0,0 @@ -// $Id$ - -#ifndef BARRIER_H -#define BARRIER_H - -#include "ace/Synch.h" -#include "ace/Atomic_Op.h" - -/* Barrier is a simple wrapper for the ACE_Barrier synchronization - class. The ACE_Barrier is already pretty easy to use but I thought - I'd wrap it up to create just a bit more abstraction at the - application level. */ - -class Barrier -{ -public: - // Basic constructor and destructor. If you only need to synch the - // start of your threads, you can safely delete your Barrier object - // after invoking done(). Of course, you should be careful to only - // delete the object once! - Barrier (void); - ~Barrier (void); - - // Set and get the number of threads that the barrier will manage. - // If you add or remove threads to your application at run-time you - // can use the mutator to reflect that change. Note, however, that - // you can only do that from the thread which first created the - // Barrier. (This is a limitation of my Barrier object, not the - // ACE_Barrier.) The optional _wait parameter will cause wait() to - // be invoked if there is already a valid threads value. - int threads (u_int threads, int wait = 0); - u_int threads (void); - - // Wait for all threads to reach the point where this is invoked. - // Because of the snappy way in which ACE_Barrier is implemented, - // you can invoke these back-to-back with no ill-effects. - int wait (void); - - // done() will invoke wait(). Before returning though, it will - // delete the barrier_ pointer below to reclaim some memory. - int done (void); - - // Reset the owning thread of the barrier. - void owner( ACE_thread_t _owner ); - -protected: - // The number of threads we're synching - ACE_Atomic_Op<ACE_Mutex, u_int> threads_; - - // The ACE_Barrier that does all of the work - ACE_Barrier *barrier_; - - // If we mutate the number of threads we have to do some black magic - // to make sure there isn't a memory leak. These two member - // variables are a part of that magic. - ACE_Barrier *new_barrier_; - ACE_Mutex barrier_mutex_; - - // The thread which created the Barrier in the first place. Only - // this thread can change the threads_ value. - ACE_thread_t owner_; - - // An internal method that constructs the barrier_ as needed. - int make_barrier (int wait); -}; - -#endif /* BARRIER_H */ diff --git a/docs/tutorials/017/Makefile b/docs/tutorials/017/Makefile deleted file mode 100644 index 21e349dd929..00000000000 --- a/docs/tutorials/017/Makefile +++ /dev/null @@ -1,77 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = barrier barrier2 - -FILES = Barrier_i - -BUILD = $(VBIN) - -LSRC = $(addsuffix .cpp,$(BIN)) -SRC = $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && $(RM) hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/017/barrier.cpp b/docs/tutorials/017/barrier.cpp deleted file mode 100644 index 93caedee8b3..00000000000 --- a/docs/tutorials/017/barrier.cpp +++ /dev/null @@ -1,166 +0,0 @@ - -// $Id$ - -#include "Barrier_i.h" -#include "ace/Task.h" - -/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/ -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - // Construct the object with a desired thread count - Test(int _threads); - - // Open/begin the test. As usual, we have to match the - // ACE_Task signature. - int open(void * _unused = 0); - - // Change the threads_ value for the next invocation of open() - void threads(int _threads); - - // Get the current threads_ value. - int threads(void); - - // Perform the test - int svc(void); - -protected: - // How many threads the barrier will test. - int threads_; - - // The Barrier object we'll use in our tests below - Barrier barrier_; -}; - -/* Construct the object & initialize the threads value for open() to - use. -*/ -Test::Test(int _threads) - : threads_(_threads) -{ -} - -/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/ -int Test::open(void * _unused) -{ - ACE_UNUSED_ARG(_unused); - - // One thing about the barrier: You have to tell it how many - // threads it will be synching. The threads() mutator on my - // Barrier class lets you do that and hides the implementation - // details at the same time. - barrier_.threads(threads_); - - // Activate the tasks as usual... Like the other cases where - // we're joining (or waiting for) our threads, we can't use - // THR_DETACHED. - return this->activate(THR_NEW_LWP, threads_); -} - -void Test::threads(int _threads) -{ - threads_ = _threads; -} - -int Test::threads(void) -{ - return threads_; -} - -/* svc() will execute in each thread & do a few things with the - Barrier we have. - */ -int Test::svc(void) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entry\n")); - - // Initialize the random number generator. We'll use this to - // create sleep() times in each thread. This will help us see - // if the barrier synch is working. - ACE_Time_Value now(ACE_OS::gettimeofday()); - ACE_RANDR_TYPE seed = now.usec(); - ACE_OS::srand(seed); - int delay; - - // After saying hello above, sleep for a random amount of time - // from 1 to 6 seconds. That will cause the next message - // "Entering wait()" to be staggered on the output as each - // thread's sleep() returns. - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // When executing the app you should see these messages - // staggered in an at-most 6 second window. That is, you - // won't likely see them all at once. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entering wait()\n")); - - // All of the threads will now wait at this point. As each - // thread finishes the sleep() above it will join the waiters. - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tbarrier_.wait() failed!\n")); - return 0; - } - - // When all threads have reached wait() they will give us this - // message. If you execute this, you should see all of the - // "Everybody together" messages at about the same time. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Everybody together?\n")); - - // Now we do the sleep() cycle again... - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // As before, these will trickle in over a few seconds. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entering done()\n")); - - // This time we call done() instead of wait(). done() - // actually invokes wait() but before returning here, it will - // clean up a few resources. The goal is to prevent carrying - // around objects you don't need. - if( barrier_.done() == -1 ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tbarrier_.done() failed!\n")); - return 0; - } - - // Since done() invokes wait() internally, we'll see this - // message from each thread simultaneously - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Is everyone still here?\n")); - - // A final sleep() - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // These should be randomly spaced like all of the other - // post-sleep messages. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Chaos and anarchy for all!\n")); - - return(0); -} - -/* Our test application... - */ -int main(int, char**) -{ - // Create the test object with 10 threads - Test test(10); - - // and open it to test the barrier. - test.open(); - // Now wait for them all to exit. - test.wait(); - - // Re-open the Test object with just 5 threads - test.threads(5); - test.open(); - // and wait for them to complete also. - test.wait(); - - return(0); -} diff --git a/docs/tutorials/017/barrier2.cpp b/docs/tutorials/017/barrier2.cpp deleted file mode 100644 index 2ed76decc34..00000000000 --- a/docs/tutorials/017/barrier2.cpp +++ /dev/null @@ -1,178 +0,0 @@ - -// $Id$ - -#include "Barrier_i.h" -#include "ace/Task.h" - -/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/ -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - // Construct the object with a desired thread count - Test(int _threads); - - // Open/begin the test. As usual, we have to match the - // ACE_Task signature. - int open(void * _unused = 0); - - // Change the threads_ value for the next invocation of open() - void threads(int _threads); - - // Get the current threads_ value. - int threads(void); - - // Perform the test - int svc(void); - -protected: - // How many threads the barrier will test. - u_int threads_; - - // The Barrier object we'll use in our tests below - Barrier barrier_; - - // This lets us pick one (eg -- the first) thread as the - // "controller" for our little test... - ACE_Atomic_Op<ACE_Mutex,u_int> tcount_; -}; - -/* Construct the object & initialize the threads value for open() to - use. -*/ -Test::Test(int _threads) - : threads_(_threads), tcount_(0) -{ -} - -/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/ -int Test::open(void * _unused) -{ - ACE_UNUSED_ARG(_unused); - - // One thing about the barrier: You have to tell it how many - // threads it will be synching. The threads() mutator on my - // Barrier class lets you do that and hides the implementation - // details at the same time. - barrier_.threads(threads_); - - // Activate the tasks as usual... - return this->activate(THR_NEW_LWP, threads_, 1); -} - -void Test::threads(int _threads) -{ - threads_ = _threads; -} - -int Test::threads(void) -{ - return threads_; -} - -/* svc() will execute in each thread & do a few things with the - Barrier we have. - */ -int Test::svc(void) -{ - // Say hello to everyone first. - ACE_DEBUG(( LM_INFO, "(%P|%t|%T) Created\n" )); - - // Increment and save the "tcount" value. We'll use it in - // just a moment... - int me = ++tcount_; - - // Wait for all initial threads to get to this point before we - // go any further. This is standard barrier usage... - barrier_.wait(); - - // Setup our random number generator. - ACE_Time_Value now(ACE_OS::gettimeofday()); - ACE_RANDR_TYPE seed = now.usec(); - ACE_OS::srand(seed); - int delay; - - // We'll arbitrarily choose the first activated thread to be - // the controller. After it sleeps a few seconds, it will add - // five threads. - if( me == 1 ) - { - // Sleep from 1 to 10 seconds so that some of the other - // threads will be into their for() loop. - delay = ACE_OS::rand_r(seed)%10; - ACE_OS::sleep(abs(delay)+1); - - // Make ourselves the barrier owner so that we can change - // the number of threads. This should be done with care... - barrier_.owner( ACE_OS::thr_self() ); - - // Add 5 threads to the barrier and then activate() to - // make them real. Notice the third parameter to - // activate(). Without this parameter, the threads won't - // be created. - if( barrier_.threads(threads_+5) == 0 ) - { - this->activate(THR_NEW_LWP,5,1); - } - } - - // This for() loop represents an "infinite" work loop in an - // application. The theory is that the threads are dividing up - // some work but need to "recalibrate" if more threads are - // added. I'll just do five iterations so that the test - // doesn't run forever. - int i; - for( i = 0 ; i < 5 ; ++i ) - { - // The sleep() represents time doing work. - delay = ACE_OS::rand_r(seed)%7; - ACE_OS::sleep(abs(delay)+1); - - ACE_DEBUG(( LM_INFO, "(%P|%t|%T)\tThread %.2d of %.2d iteration %.2d\n", me, threads_, i )); - - // If the local threads_ variable doesn't match the number - // in the barrier, then the controller must have changed - // the thread count. We'll wait() for everyone and then - // recalibrate ourselves before continuing. - if( this->threads_ != barrier_.threads() ) - { - ACE_DEBUG(( LM_INFO, "(%P|%t|%T) Waiting for thread count to increase to %d from %d\n", - barrier_.threads(), this->threads_ )); - - // Wait for all our sibling threads... - barrier_.wait(); - - // Set our local variable so that we don't come here again. - this->threads_ = barrier_.threads(); - - // Recalibration can be anything you want. At this - // point, we know that all of the threads are synch'd - // and ready to go. - } - } - - // Re-synch all of the threads before they exit. This isn't - // really necessary but I like to do it. - barrier_.done(); - - return(0); -} - -/* Our test application... - */ -int main(int, char**) -{ - // Create the test object with 5 threads - Test test(5); - - // and open it to test the barrier. - test.open(); - // Now wait for them all to exit. - test.wait(); - - return(0); -} diff --git a/docs/tutorials/017/combine.shar b/docs/tutorials/017/combine.shar deleted file mode 100644 index c50680b0bd2..00000000000 --- a/docs/tutorials/017/combine.shar +++ /dev/null @@ -1,380 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 2000-03-19 15:00 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/home/jcej/projects/ACE_wrappers/docs/tutorials/017'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 422 -rw-rw-r-- hdr -# 65 -rw-rw-r-- bodies -# 1393 -rw-rw-r-- page01.pre -# 420 -rw-rw-r-- page02.pre -# 736 -rw-rw-r-- page03.pre -# 479 -rw-rw-r-- page04.pre -# 375 -rw-rw-r-- page05.pre -# 374 -rw-rw-r-- page06.pre -# 216 -rw-rw-r-- page05.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh00331; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 03191459100 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -9991b747f6aff75784cbeb88a79c06fc hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 422 -eq "$shar_count" || - $echo 'hdr:' 'original size' '422,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -barrier.cpp -Barrier_i.h -Barrier_i.cpp -PAGE=6 -barrier2.cpp -SHAR_EOF - $shar_touch -am 0224165499 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -95ff65d56968b60df92224ca27a34387 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 65 -eq "$shar_count" || - $echo 'bodies:' 'original size' '65,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -The ACE_Barrier implements the barrier synchronization pattern. -<P> -That's nice. What does it mean? -<P> -What it means is that you can use the ACE_Barrier to cause a set of -threads to all wait at a specific point in your application. In other -words: the threads reach a barrier that none can pass until all are -present. -<P> -This would typically be used in scientific applications where a set of -threads are all working in parallel on some great computation but they -have to synch and summarize before continuing to the next stage of calculation. With -proper use of ACE_Barrier, the threads can easily synch before -continuing. -<P> -In this tutorial I'll create a simple wrapper for the ACE_Barrier. In -reality, the ACE_Barrier is so easy that a wrapper isn't really -needed. I created the wrapper anyway though just because I wanted to. -<P> -Kirthika's abstract: -<ul> -The ACE_Barrier class is used for collective thread syncronisation. All -the threads block at the barrier and advance only after everyone is at -the -barrier. A thread blocks by calling the wait() method and stays until -all the other threads invoke wait() one-by-one at the barrier and then -all -move ahead. -Here, an abstract barrier class is created which incorporates the -ACE_Barrier -mechanism and is used in a test case of an ACE_Task with 10 and 5 -threads respectively -which illustrate the use of the barrier pattern. -</ul> -SHAR_EOF - $shar_touch -am 03191459100 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -6d94644272d64ed997ae76b98475d84e page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 1393 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '1393,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -First, lets take a look at the main() routine and how it will use the -Barrier wrapper class. A simple ACE_Task derivative is used so that -we can perform work in multiple threads. These threads will use the -barrier to synch in a couple of places. -<P> -Obviously this isn't a very realistic example but you should be able -to get the idea of how to use a Barrier without getting hung up in -application-level details. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -9e2b4b85abf1bff15b94b6d20bc20f91 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 420 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '420,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -The Barrier class used by the test task is a simple wrapper around -ACE_Barrier. One of the things about ACE_Barrier is that you have to -tell it how many threads it will be managing. Since that number -usually isn't known when you create your Task derivative, you have to -dynamically allocate the ACE_Barrier. My Barrier wrapper takes care -of that for you and even provides for a clean way to delete the -ACE_Barrier instance if you want to save a few bytes. -<P> -An interesting extension of this Barrier class would be to wrap it up -in a smart pointer. You could then have the Barrier destructor invoke -wait() as a now-protected method. The result would allow you to treat -the Barrier object almost as a "synchronization guard". -<HR> -SHAR_EOF - $shar_touch -am 03191459100 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -4d6cead716800d7625b2a903d0df1b34 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 736 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '736,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -The Barrier implementation is quite simple. The threads() mutator -took a couple of tries to get right. In particular, be sure you know -when to apply the _wait paramter and when not to! In fact, the -requirement that only the "owning" thread can change the thread count -is rather limiting. A more appropriate solution would allow any -thread to safely change the count but that would require more complex -locking that is just a bit more than what I wanted to present here. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -0c46b51370a57179cea56ef57fd0b1f4 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 479 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '479,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -Well, that's it for the simple Barrier Tutorial. I encourage you to -try it out and see what you like and dislike. Any improvements or -enhancements will gladly be integrated into the Tutorial. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="barrier.cpp">barrier.cpp</A> -<LI><A HREF="Barrier_i.h">Barrier_i.h</A> -<LI><A HREF="Barrier_i.cpp">Barrier_i.cpp</A> -</UL> -SHAR_EOF - $shar_touch -am 03191459100 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -616a2293adddb11896d28c7172436a65 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 375 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '375,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -I could have included this in the first Test object of the tutorial -but that may have complicated things a bit. What we're doing here is -recognizing when the "owner" thread adds more threads to the pool. -When we notice that, we use the barrier to wait until everything -stabilizes and then we recalibrate and move on. -<P> -The source is <A HREF="barrier2.cpp">here</A>. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -0e05cdb27f2d6bfda8fc2246ed981aab page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 374 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '374,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pst ============== -if test -f 'page05.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pst' '(file already exists)' -else - $echo 'x -' extracting 'page05.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pst' && -<HR> -Before we call it a wrap though, there's one more thing I want to show -you. Remember the comments around Barrier::threads()? On the next -page, I'll show you how to synch up when the number of threads changes. -SHAR_EOF - $shar_touch -am 03191459100 'page05.pst' && - chmod 0664 'page05.pst' || - $echo 'restore of' 'page05.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pst:' 'MD5 check failed' -4f18e2b82827f498992bd11b36c4ca09 page05.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pst'`" - test 216 -eq "$shar_count" || - $echo 'page05.pst:' 'original size' '216,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh00331 -exit 0 diff --git a/docs/tutorials/017/page01.html b/docs/tutorials/017/page01.html deleted file mode 100644 index a2ff33ca8ca..00000000000 --- a/docs/tutorials/017/page01.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The ACE_Barrier implements the barrier synchronization pattern. -<P> -That's nice. What does it mean? -<P> -What it means is that you can use the ACE_Barrier to cause a set of -threads to all wait at a specific point in your application. In other -words: the threads reach a barrier that none can pass until all are -present. -<P> -This would typically be used in scientific applications where a set of -threads are all working in parallel on some great computation but they -have to synch and summarize before continuing to the next stage of calculation. With -proper use of ACE_Barrier, the threads can easily synch before -continuing. -<P> -In this tutorial I'll create a simple wrapper for the ACE_Barrier. In -reality, the ACE_Barrier is so easy that a wrapper isn't really -needed. I created the wrapper anyway though just because I wanted to. -<P> -Kirthika's abstract: -<ul> -The ACE_Barrier class is used for collective thread syncronisation. All -the threads block at the barrier and advance only after everyone is at -the -barrier. A thread blocks by calling the wait() method and stays until -all the other threads invoke wait() one-by-one at the barrier and then -all -move ahead. -Here, an abstract barrier class is created which incorporates the -ACE_Barrier -mechanism and is used in a test case of an ACE_Task with 10 and 5 -threads respectively -which illustrate the use of the barrier pattern. -</ul> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/017/page02.html b/docs/tutorials/017/page02.html deleted file mode 100644 index 81aeb9d0b8b..00000000000 --- a/docs/tutorials/017/page02.html +++ /dev/null @@ -1,195 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -First, lets take a look at the main() routine and how it will use the -Barrier wrapper class. A simple ACE_Task derivative is used so that -we can perform work in multiple threads. These threads will use the -barrier to synch in a couple of places. -<P> -Obviously this isn't a very realistic example but you should be able -to get the idea of how to use a Barrier without getting hung up in -application-level details. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Barrier_i.h</font>" -<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>" - -<font color=red>/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/</font> -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - <font color=red>// Construct the object with a desired thread count</font> - Test(int _threads); - - <font color=red>// Open/begin the test. As usual, we have to match the</font> - <font color=red>// ACE_Task signature.</font> - int open(void * _unused = 0); - - <font color=red>// Change the threads_ value for the next invocation of open()</font> - void threads(int _threads); - - <font color=red>// Get the current threads_ value.</font> - int threads(void); - - <font color=red>// Perform the test</font> - int svc(void); - -protected: - <font color=red>// How many threads the barrier will test.</font> - int threads_; - - <font color=red>// The Barrier object we'll use in our tests below</font> - Barrier barrier_; -}; - -<font color=red>/* Construct the object & initialize the threads value for open() to - use. -*/</font> -<font color=#008888>Test::Test</font>(int _threads) - : threads_(_threads) -{ -} - -<font color=red>/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/</font> -int <font color=#008888>Test::open</font>(void * _unused) -{ - ACE_UNUSED_ARG(_unused); - - <font color=red>// One thing about the barrier: You have to tell it how many</font> - <font color=red>// threads it will be synching. The threads() mutator on my</font> - <font color=red>// Barrier class lets you do that and hides the implementation</font> - <font color=red>// details at the same time.</font> - barrier_.threads(threads_); - - <font color=red>// Activate the tasks as usual... Like the other cases where</font> - <font color=red>// we're joining (or waiting for) our threads, we can't use</font> - <font color=red>// THR_DETACHED.</font> - return this->activate(THR_NEW_LWP, threads_); -} - -void <font color=#008888>Test::threads</font>(int _threads) -{ - threads_ = _threads; -} - -int <font color=#008888>Test::threads</font>(void) -{ - return threads_; -} - -<font color=red>/* svc() will execute in each thread & do a few things with the - Barrier we have. - */</font> -int <font color=#008888>Test::svc</font>(void) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entry\n</font>")); - - <font color=red>// Initialize the random number generator. We'll use this to</font> - <font color=red>// create sleep() times in each thread. This will help us see</font> - <font color=red>// if the barrier synch is working.</font> - ACE_Time_Value now(<font color=#008888>ACE_OS::gettimeofday</font>()); - ACE_RANDR_TYPE seed = now.usec(); - <font color=#008888>ACE_OS::srand</font>(seed); - int delay; - - <font color=red>// After saying hello above, sleep for a random amount of time</font> - <font color=red>// from 1 to 6 seconds. That will cause the next message</font> - <font color=red>// "<font color=green>Entering wait()</font>" to be staggered on the output as each</font> - <font color=red>// thread's sleep() returns.</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// When executing the app you should see these messages</font> - <font color=red>// staggered in an at-most 6 second window. That is, you</font> - <font color=red>// won't likely see them all at once.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entering wait()\n</font>")); - - <font color=red>// All of the threads will now wait at this point. As each</font> - <font color=red>// thread finishes the sleep() above it will join the waiters.</font> - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tbarrier_.wait() failed!\n</font>")); - return 0; - } - - <font color=red>// When all threads have reached wait() they will give us this</font> - <font color=red>// message. If you execute this, you should see all of the</font> - <font color=red>// "<font color=green>Everybody together</font>" messages at about the same time.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Everybody together?\n</font>")); - - <font color=red>// Now we do the sleep() cycle again...</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// As before, these will trickle in over a few seconds.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entering done()\n</font>")); - - <font color=red>// This time we call done() instead of wait(). done()</font> - <font color=red>// actually invokes wait() but before returning here, it will</font> - <font color=red>// clean up a few resources. The goal is to prevent carrying</font> - <font color=red>// around objects you don't need.</font> - if( barrier_.done() == -1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tbarrier_.done() failed!\n</font>")); - return 0; - } - - <font color=red>// Since done() invokes wait() internally, we'll see this</font> - <font color=red>// message from each thread simultaneously</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Is everyone still here?\n</font>")); - - <font color=red>// A final sleep()</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// These should be randomly spaced like all of the other</font> - <font color=red>// post-sleep messages.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Chaos and anarchy for all!\n</font>")); - - return(0); -} - -<font color=red>/* Our test application... - */</font> -int main(int, char**) -{ - <font color=red>// Create the test object with 10 threads</font> - Test test(10); - - <font color=red>// and open it to test the barrier.</font> - test.open(); - <font color=red>// Now wait for them all to exit.</font> - test.wait(); - - <font color=red>// Re-open the Test object with just 5 threads</font> - test.threads(5); - test.open(); - <font color=red>// and wait for them to complete also.</font> - test.wait(); - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/017/page03.html b/docs/tutorials/017/page03.html deleted file mode 100644 index fe2d6ec5eda..00000000000 --- a/docs/tutorials/017/page03.html +++ /dev/null @@ -1,100 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Barrier class used by the test task is a simple wrapper around -ACE_Barrier. One of the things about ACE_Barrier is that you have to -tell it how many threads it will be managing. Since that number -usually isn't known when you create your Task derivative, you have to -dynamically allocate the ACE_Barrier. My Barrier wrapper takes care -of that for you and even provides for a clean way to delete the -ACE_Barrier instance if you want to save a few bytes. -<P> -An interesting extension of this Barrier class would be to wrap it up -in a smart pointer. You could then have the Barrier destructor invoke -wait() as a now-protected method. The result would allow you to treat -the Barrier object almost as a "synchronization guard". -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>BARRIER_H</font> -<font color=blue>#define</font> <font color=purple>BARRIER_H</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Synch.h">ace/Synch.h</A>" -<font color=blue>#include</font> "<A HREF="../../../ace/Atomic_Op.h">ace/Atomic_Op.h</A>" - -<font color=red>/* Barrier is a simple wrapper for the ACE_Barrier synchronization - class. The ACE_Barrier is already pretty easy to use but I thought - I'd wrap it up to create just a bit more abstraction at the - application level. */</font> - -class Barrier -{ -public: - <font color=red>// Basic constructor and destructor. If you only need to synch the</font> - <font color=red>// start of your threads, you can safely delete your Barrier object</font> - <font color=red>// after invoking done(). Of course, you should be careful to only</font> - <font color=red>// delete the object once!</font> - Barrier (void); - ~Barrier (void); - - <font color=red>// Set and get the number of threads that the barrier will manage.</font> - <font color=red>// If you add or remove threads to your application at run-time you</font> - <font color=red>// can use the mutator to reflect that change. Note, however, that</font> - <font color=red>// you can only do that from the thread which first created the</font> - <font color=red>// Barrier. (This is a limitation of my Barrier object, not the</font> - <font color=red>// ACE_Barrier.) The optional _wait parameter will cause wait() to</font> - <font color=red>// be invoked if there is already a valid threads value.</font> - int threads (u_int threads, int wait = 0); - u_int threads (void); - - <font color=red>// Wait for all threads to reach the point where this is invoked.</font> - <font color=red>// Because of the snappy way in which ACE_Barrier is implemented,</font> - <font color=red>// you can invoke these back-to-back with no ill-effects.</font> - int wait (void); - - <font color=red>// done() will invoke wait(). Before returning though, it will</font> - <font color=red>// delete the barrier_ pointer below to reclaim some memory.</font> - int done (void); - - <font color=red>// Reset the owning thread of the barrier.</font> - void owner( ACE_thread_t _owner ); - -protected: - <font color=red>// The number of threads we're synching</font> - ACE_Atomic_Op<ACE_Mutex, u_int> threads_; - - <font color=red>// The ACE_Barrier that does all of the work</font> - ACE_Barrier *barrier_; - - <font color=red>// If we mutate the number of threads we have to do some black magic</font> - <font color=red>// to make sure there isn't a memory leak. These two member</font> - <font color=red>// variables are a part of that magic.</font> - ACE_Barrier *new_barrier_; - ACE_Mutex barrier_mutex_; - - <font color=red>// The thread which created the Barrier in the first place. Only</font> - <font color=red>// this thread can change the threads_ value.</font> - ACE_thread_t owner_; - - <font color=red>// An internal method that constructs the barrier_ as needed.</font> - int make_barrier (int wait); -}; - -<font color=blue>#endif</font> <font color=red>/* BARRIER_H */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/017/page04.html b/docs/tutorials/017/page04.html deleted file mode 100644 index 01aea4ed8c4..00000000000 --- a/docs/tutorials/017/page04.html +++ /dev/null @@ -1,188 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Barrier implementation is quite simple. The threads() mutator -took a couple of tries to get right. In particular, be sure you know -when to apply the _wait paramter and when not to! In fact, the -requirement that only the "owning" thread can change the thread count -is rather limiting. A more appropriate solution would allow any -thread to safely change the count but that would require more complex -locking that is just a bit more than what I wanted to present here. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Barrier_i.h</font>" - -<font color=red>/* Initialize the threads_ count to zero and the barrier_ pointer to a - safe value. At the same time, we remember the thread that created - us so that we can allow it to change the thread count. -*/</font> -<font color=#008888>Barrier::Barrier</font>(void) - : threads_(0) - ,barrier_(0) - ,new_barrier_(0) -{ - owner_ = <font color=#008888>ACE_OS::thr_self</font>(); -} - -<font color=red>/* Ensure that barrier_ get's deleted so that we don't have a memory leak. - */</font> -<font color=#008888>Barrier::~Barrier</font>(void) -{ - delete barrier_; -} - -void <font color=#008888>Barrier::owner</font>( ACE_thread_t _owner ) -{ - owner_ = _owner; -} - -<font color=red>// Report on the number of threads.</font> -u_int <font color=#008888>Barrier::threads</font>(void) -{ - return threads_.value(); -} - -<font color=red>/* Allow the owning thread to (re)set the number of threads. - make_barrier() is called because it will wait() if we were already - configured. Typical usage would be for the worker threads to - wait() while the primary (eg -- owner) thread adjusts the thread - count. - - For instance: - In the worker threads: - if( myBarrier.threads() != current_thread_count ) - myBarrier.wait(); - - In the primary thread: - if( myBarrier.threads() != current_thread_count ) - myBarrier.threads( current_thread_count, 1 ); - */</font> -int <font color=#008888>Barrier::threads</font>( u_int _threads, int _wait ) -{ - if( ! <font color=#008888>ACE_OS::thr_equal</font>(ACE_OS::thr_self(), owner_) ) - { - return -1; - } - - threads_ = _threads; - - return make_barrier(_wait); -} - -<font color=red>/* Wait for all threads to synch if the thread count is valid. Note - that barrier_ will be 0 if the threads() mutator has not been - invoked. -*/</font> -int <font color=#008888>Barrier::wait</font>(void) -{ - if( ! barrier_ ) - { - return -1; - } - - <font color=red>// If the threads() mutator has been used, new_barrier_ will</font> - <font color=red>// point to a new ACE_Barrier instance. We'll use a</font> - <font color=red>// traditional double-check here to move that new object into</font> - <font color=red>// place and cleanup the old one.</font> - if( new_barrier_ ) - { - <font color=red>// mutex so that only one thread can do this part.</font> - ACE_Guard<ACE_Mutex> mutex(barrier_mutex_); - - <font color=red>// We only want the first thread to plug in the new barrier...</font> - if( new_barrier_ ) - { - <font color=red>// out with the old and in with the new.</font> - delete barrier_; - barrier_ = new_barrier_; - new_barrier_ = 0; - } - } - - return barrier_->wait(); -} - -<font color=red>/* Wait for all threads to synch. As each thread passes wait(), it - will decrement our thread counter. (That is why we had to make - threads_ an atomic op.) When the last thread decrements the - counter it will also delete the ACE_Barrier & free up a little - memory. -*/</font> -int <font color=#008888>Barrier::done</font>(void) -{ - if( this->wait() == -1 ) - { - return -1; - } - - --threads_; - - if( ! threads_.value() ) - { - delete barrier_; - barrier_ = 0; - } - - return 0; -} - -<font color=red>/* This will build the actual barrier. I broke this code out of the - threads() mutator in case it might be useful elsewhere. - If a barrier already exists, we will wait for all threads before - creating a new one. This trait is what allows the threads mutator - to be used as shown above. - */</font> -int <font color=#008888>Barrier::make_barrier</font>( int _wait ) -{ - <font color=red>// Ensure we have a valid thread count.</font> - if( ! threads_.value() ) - { - return -1; - } - - <font color=red>// If a barrier already exists, we'll arrange for it to be</font> - <font color=red>// replaced through the wait() method above.</font> - if( barrier_ ) - { - <font color=red>// Create the new barrier that wait() will install for us.</font> - ACE_NEW_RETURN(new_barrier_,ACE_Barrier(threads_.value()),-1); - - <font color=red>// Wait for our siblings to synch before continuing</font> - if( _wait ) - { - barrier_->wait(); - } - } - else - { - <font color=red>// Create the initial barrier.</font> - ACE_NEW_RETURN(barrier_,ACE_Barrier(threads_.value()),-1); - } - - return 0; -} - -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Atomic_Op <ACE_Mutex, u_int>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Atomic_Op <ACE_Mutex, u_int> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/017/page05.html b/docs/tutorials/017/page05.html deleted file mode 100644 index 1fc924890fc..00000000000 --- a/docs/tutorials/017/page05.html +++ /dev/null @@ -1,32 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Well, that's it for the simple Barrier Tutorial. I encourage you to -try it out and see what you like and dislike. Any improvements or -enhancements will gladly be integrated into the Tutorial. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="barrier.cpp">barrier.cpp</A> -<LI><A HREF="Barrier_i.h">Barrier_i.h</A> -<LI><A HREF="Barrier_i.cpp">Barrier_i.cpp</A> -</UL> -<HR> -Before we call it a wrap though, there's one more thing I want to show -you. Remember the comments around Barrier::threads()? On the next -page, I'll show you how to synch up when the number of threads changes. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/017/page06.html b/docs/tutorials/017/page06.html deleted file mode 100644 index 8e3704b1b32..00000000000 --- a/docs/tutorials/017/page06.html +++ /dev/null @@ -1,206 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -I could have included this in the first Test object of the tutorial -but that may have complicated things a bit. What we're doing here is -recognizing when the "owner" thread adds more threads to the pool. -When we notice that, we use the barrier to wait until everything -stabilizes and then we recalibrate and move on. -<P> -The source is <A HREF="barrier2.cpp">here</A>. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Barrier_i.h</font>" -<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>" - -<font color=red>/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/</font> -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - <font color=red>// Construct the object with a desired thread count</font> - Test(int _threads); - - <font color=red>// Open/begin the test. As usual, we have to match the</font> - <font color=red>// ACE_Task signature.</font> - int open(void * _unused = 0); - - <font color=red>// Change the threads_ value for the next invocation of open()</font> - void threads(int _threads); - - <font color=red>// Get the current threads_ value.</font> - int threads(void); - - <font color=red>// Perform the test</font> - int svc(void); - -protected: - <font color=red>// How many threads the barrier will test.</font> - u_int threads_; - - <font color=red>// The Barrier object we'll use in our tests below</font> - Barrier barrier_; - - <font color=red>// This lets us pick one (eg -- the first) thread as the</font> - <font color=red>// "<font color=green>controller</font>" for our little test...</font> - ACE_Atomic_Op<ACE_Mutex,u_int> tcount_; -}; - -<font color=red>/* Construct the object & initialize the threads value for open() to - use. -*/</font> -<font color=#008888>Test::Test</font>(int _threads) - : threads_(_threads), tcount_(0) -{ -} - -<font color=red>/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/</font> -int <font color=#008888>Test::open</font>(void * _unused) -{ - ACE_UNUSED_ARG(_unused); - - <font color=red>// One thing about the barrier: You have to tell it how many</font> - <font color=red>// threads it will be synching. The threads() mutator on my</font> - <font color=red>// Barrier class lets you do that and hides the implementation</font> - <font color=red>// details at the same time.</font> - barrier_.threads(threads_); - - <font color=red>// Activate the tasks as usual...</font> - return this->activate(THR_NEW_LWP, threads_, 1); -} - -void <font color=#008888>Test::threads</font>(int _threads) -{ - threads_ = _threads; -} - -int <font color=#008888>Test::threads</font>(void) -{ - return threads_; -} - -<font color=red>/* svc() will execute in each thread & do a few things with the - Barrier we have. - */</font> -int <font color=#008888>Test::svc</font>(void) -{ - <font color=red>// Say hello to everyone first.</font> - ACE_DEBUG(( LM_INFO, "<font color=green>(%P|%t|%T) Created\n</font>" )); - - <font color=red>// Increment and save the "<font color=green>tcount</font>" value. We'll use it in</font> - <font color=red>// just a moment...</font> - int me = ++tcount_; - - <font color=red>// Wait for all initial threads to get to this point before we</font> - <font color=red>// go any further. This is standard barrier usage...</font> - barrier_.wait(); - - <font color=red>// Setup our random number generator.</font> - ACE_Time_Value now(<font color=#008888>ACE_OS::gettimeofday</font>()); - ACE_RANDR_TYPE seed = now.usec(); - <font color=#008888>ACE_OS::srand</font>(seed); - int delay; - - <font color=red>// We'll arbitrarily choose the first activated thread to be</font> - <font color=red>// the controller. After it sleeps a few seconds, it will add</font> - <font color=red>// five threads.</font> - if( me == 1 ) - { - <font color=red>// Sleep from 1 to 10 seconds so that some of the other</font> - <font color=red>// threads will be into their for() loop.</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%10; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// Make ourselves the barrier owner so that we can change</font> - <font color=red>// the number of threads. This should be done with care...</font> - barrier_.owner( <font color=#008888>ACE_OS::thr_self</font>() ); - - <font color=red>// Add 5 threads to the barrier and then activate() to</font> - <font color=red>// make them real. Notice the third parameter to</font> - <font color=red>// activate(). Without this parameter, the threads won't</font> - <font color=red>// be created.</font> - if( barrier_.threads(threads_+5) == 0 ) - { - this->activate(THR_NEW_LWP,5,1); - } - } - - <font color=red>// This for() loop represents an "<font color=green>infinite</font>" work loop in an</font> - <font color=red>// application. The theory is that the threads are dividing up</font> - <font color=red>// some work but need to "<font color=green>recalibrate</font>" if more threads are</font> - <font color=red>// added. I'll just do five iterations so that the test</font> - <font color=red>// doesn't run forever.</font> - int i; - for( i = 0 ; i < 5 ; ++i ) - { - <font color=red>// The sleep() represents time doing work.</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%7; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - ACE_DEBUG(( LM_INFO, "<font color=green>(%P|%t|%T)\tThread %.2d of %.2d iteration %.2d\n</font>", me, threads_, i )); - - <font color=red>// If the local threads_ variable doesn't match the number</font> - <font color=red>// in the barrier, then the controller must have changed</font> - <font color=red>// the thread count. We'll wait() for everyone and then</font> - <font color=red>// recalibrate ourselves before continuing.</font> - if( this->threads_ != barrier_.threads() ) - { - ACE_DEBUG(( LM_INFO, "<font color=green>(%P|%t|%T) Waiting for thread count to increase to %d from %d\n</font>", - barrier_.threads(), this->threads_ )); - - <font color=red>// Wait for all our sibling threads...</font> - barrier_.wait(); - - <font color=red>// Set our local variable so that we don't come here again.</font> - this->threads_ = barrier_.threads(); - - <font color=red>// Recalibration can be anything you want. At this</font> - <font color=red>// point, we know that all of the threads are synch'd</font> - <font color=red>// and ready to go.</font> - } - } - - <font color=red>// Re-synch all of the threads before they exit. This isn't</font> - <font color=red>// really necessary but I like to do it.</font> - barrier_.done(); - - return(0); -} - -<font color=red>/* Our test application... - */</font> -int main(int, char**) -{ - <font color=red>// Create the test object with 5 threads</font> - Test test(5); - - <font color=red>// and open it to test the barrier.</font> - test.open(); - <font color=red>// Now wait for them all to exit.</font> - test.wait(); - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> - |