Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

TestFlushQueue.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Created on Tue Oct  7 09:09:12 PDT 1997 by heydon
00020 // Last modified on Mon May 23 22:29:34 EDT 2005 by ken@xorian.net  
00021 //      modified on Mon Feb 14 18:27:21 PST 2000 by mann  
00022 //      modified on Sun Aug 23 12:14:14 PDT 1998 by heydon
00023 
00024 #include <stdlib.h> // for rand_r(3)
00025 // add declaration to fix broken <stdlib.h>
00026 extern "C" int _Prand_r(unsigned int *seedptr);
00027 
00028 #include <Basics.H>
00029 #include "FlushQueue.H"
00030 
00031 using std::cout;
00032 using std::cerr;
00033 using std::endl;
00034 
00035 static Basics::mutex mu;
00036 static FlushQueue *q;
00037 
00038 static void Syntax(char *msg, char *arg = (char *)NULL) throw ()
00039 {
00040     cerr << "Error: " << msg;
00041     if (arg != (char *)NULL) cerr << ": `" << arg << "'";
00042     cerr << endl;
00043     cerr << "Syntax: TestFlushQueue [ -threads num ] [ -pause msecs ]" << endl;
00044     exit(1);
00045 }
00046 
00047 class ThreadArgs {
00048   public:
00049     ThreadArgs(int threadId, int msecPause) throw ()
00050         : threadId(threadId), msecPause(msecPause) { /*SKIP*/ }
00051     Basics::thread th;
00052     int threadId;
00053     int msecPause;
00054 };
00055 
00056 static void Pause(int total_msecs) throw ()
00057 {
00058     int secs = total_msecs / 1000;
00059     int msecs = total_msecs % 1000;
00060     Basics::thread::pause(secs, msecs);
00061 }
00062 
00063 static void* ThreadBody(void *voidarg) throw ()
00064 // "voidarg" is actually of type "ThreadArgs *"
00065 {
00066     ThreadArgs *args = (ThreadArgs *)voidarg;
00067     unsigned int seed = args->threadId;
00068     while (true) {
00069         // random pause
00070         int r = rand_r(&seed);
00071         unsigned long pause = 5L * (long)(args->msecPause) * (long)r;
00072         Pause((int)(pause / RAND_MAX));
00073         
00074         // enqueue
00075         mu.lock();
00076         cout << "Thread " << args->threadId << ": enqueued" << endl;
00077         q->Enqueue();
00078         cout << "Thread " << args->threadId << ": working" << endl;
00079         mu.unlock();
00080 
00081         // do work
00082         Pause(args->msecPause);
00083 
00084         // dequeue
00085         mu.lock();
00086         cout << "Thread " << args->threadId << ": dequeued" << endl;
00087         q->Dequeue();
00088         mu.unlock();
00089 
00090     }
00091 
00092     //return (void *)NULL; // not reached
00093 }
00094 
00095 int main(int argc, char *argv[]) 
00096 {
00097     // command-line args
00098     int numThreads = 5;
00099     int msecPause = 300;
00100 
00101     // parse command-line
00102     int arg = 1;
00103     while (arg < argc) {
00104         char *curr = argv[arg];
00105         if (*curr == '-') {
00106             if (!strcmp(curr, "-threads")) {
00107                 arg++;
00108                 if (arg < argc) {
00109                     if (sscanf(argv[arg], "%d", &numThreads) != 1) {
00110                         Syntax("illegal argument to -threads", argv[arg]);
00111                     }
00112                     arg++;
00113                 } else {
00114                     Syntax("no argument supplied to switch", curr);
00115                 }
00116             } else if (!strcmp(curr, "-pause")) {
00117                 arg++;
00118                 if (arg < argc) {
00119                     if (sscanf(argv[arg], "%d", &msecPause) != 1) {
00120                         Syntax("illegal argument to -pause", argv[arg]);
00121                     }
00122                     arg++;
00123                 } else {
00124                     Syntax("no argument supplied to switch", curr);
00125                 }
00126             } else {
00127                 Syntax("unrecognized switch", curr);
00128             }
00129         } else {
00130             Syntax("unrecognized argument", curr);
00131         }
00132     }
00133     assert(arg == argc);
00134 
00135     // initialize queue
00136     q = NEW_CONSTR(FlushQueue, (&mu));
00137 
00138     // fork threads
00139     for (int i = 0; i < numThreads; i++) {
00140       ThreadArgs *args = NEW_PTRFREE_CONSTR(ThreadArgs, (i + 1, msecPause));
00141       args->th.fork_and_detach(ThreadBody, (void *)args);
00142     }
00143 
00144     // pause indefinitely
00145     Basics::cond c;
00146     mu.lock();
00147     while (true) c.wait(mu);
00148     //mu.unlock(); // not reached
00149 }

Generated on Mon May 8 00:48:36 2006 for Vesta by  doxygen 1.4.2