Index: /branches/eam_branch_20080719/psLib/src/pslib_strict.h
===================================================================
--- /branches/eam_branch_20080719/psLib/src/pslib_strict.h	(revision 18748)
+++ /branches/eam_branch_20080719/psLib/src/pslib_strict.h	(revision 18749)
@@ -9,6 +9,6 @@
 *  @author Eric Van Alst, MHPCC
 *
-*  @version $Revision: 1.36 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2008-06-16 21:58:42 $
+*  @version $Revision: 1.36.8.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2008-07-26 03:48:39 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -116,3 +116,5 @@
 #include "psTree.h"
 
+#include "psThread.h"
+
 #endif // #ifndef PS_LIB_STRICT_H
Index: /branches/eam_branch_20080719/psLib/src/sys/Makefile.am
===================================================================
--- /branches/eam_branch_20080719/psLib/src/sys/Makefile.am	(revision 18748)
+++ /branches/eam_branch_20080719/psLib/src/sys/Makefile.am	(revision 18749)
@@ -14,4 +14,5 @@
 	psSlurp.c      \
 	psString.c     \
+	psThread.c     \
 	psTrace.c      \
 	psType.c       \
@@ -42,4 +43,5 @@
 	psSlurp.h      \
 	psString.h     \
+	psThread.h     \
 	psTrace.h      \
 	psType.h
Index: /branches/eam_branch_20080719/psLib/src/sys/psThread.c
===================================================================
--- /branches/eam_branch_20080719/psLib/src/sys/psThread.c	(revision 18749)
+++ /branches/eam_branch_20080719/psLib/src/sys/psThread.c	(revision 18749)
@@ -0,0 +1,134 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "psAssert.h"
+#include "psConstants.h"
+#include "psAbort.h"
+#include "psMemory.h"
+#include "psList.h"
+#include "psArray.h"
+#include "psString.h"
+#include "psThread.h"
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static psList *queue = NULL;		// queue of pending jobs
+static psArray *pool = NULL;		// array of defined threads
+
+void psThreadLock () {
+    pthread_mutex_lock (&mutex);
+    return;
+}
+
+void psThreadUnlock () {
+    pthread_mutex_unlock (&mutex);
+    return;
+}
+
+void psThreadJobFree (psThreadJob *job) {
+
+    if (!job) return;
+
+    psFree (job->type);
+    psFree (job->args);
+    return;
+}
+
+// allocate a psThreadJob with nArgs arguments
+psThreadJob *psThreadJobAlloc (char *type, int nArgs) {
+    
+    psThreadJob *job = (psThreadJob *)psAlloc(sizeof(psThreadJob));
+    psMemSetDeallocator(job, (psFreeFunc)psThreadJobFree);
+
+    job->type = psStringCopy (type);
+    job->args = psArrayAllocEmpty (nArgs);
+    return job;
+}
+
+// add a job to the queue of active jobs
+bool psThreadJobAddToQueue (psThreadJob *job) {
+
+    psThreadLock ();
+    if (queue == NULL) {
+	queue = psListAlloc(NULL);
+    }
+
+    psListAdd (queue, PS_LIST_TAIL, job);
+    psThreadUnlock ();
+    return true;
+}
+
+// this function is not locked -- see thread launder for example
+psThreadJob *psThreadJobGet () {
+
+    psThreadJob *job = psListGetAndRemove (queue, PS_LIST_HEAD);
+    return job;
+}
+
+void psThreadFree (psThread *thread) {
+    return;
+}
+
+// allocate a psThread
+psThread *psThreadAlloc () {
+    
+    psThread *thread = (psThread *)psAlloc(sizeof(psThread));
+    psMemSetDeallocator(thread, (psFreeFunc)psThreadFree);
+
+    thread->busy  = false;
+    thread->fault = false;
+    return thread;
+}
+
+// create a pool of Nthreads, each running the user's job-launcher function
+bool psThreadPoolInit (int nThreads, psThreadLaunchJobsFunction function) {
+
+    if (pool) psAbort ("psThreadsInit already called"); 
+	
+    pool = psArrayAlloc (nThreads);
+    for (int i = 0; i < nThreads; i++) {
+	psThread *thread = psThreadAlloc();
+	pthread_create (&thread->pt, NULL, function, thread);
+	pool->data[i] = thread;
+    }
+    return true;
+}
+
+// call this function after you have added jobs to the queue and 
+bool psThreadPoolWait () {
+
+    // this function blocks (waits in usleep) until either
+    // an error is detected on one of the threads or until 
+    // all threads are idle and no jobs are left on the queue
+
+    while (1) {
+
+	// check for an error
+	for (int i = 0; i < pool->n; i++) {
+	    psThread *thread = pool->data[i];
+	    if (thread->fault) return false;
+	}
+
+	// are all threads idle?
+	psThreadLock();
+	for (int i = 0; i < pool->n; i++) {
+	    psThread *thread = pool->data[i];
+	    if (thread->busy) goto SLEEP;
+	}
+
+	// is the queue empty?
+	if (queue->head == NULL) {
+	    psThreadUnlock();
+	    return true;
+	}
+
+    SLEEP:
+	psThreadUnlock();
+	usleep (10000);
+    }
+    return false;
+}
Index: /branches/eam_branch_20080719/psLib/src/sys/psThread.h
===================================================================
--- /branches/eam_branch_20080719/psLib/src/sys/psThread.h	(revision 18749)
+++ /branches/eam_branch_20080719/psLib/src/sys/psThread.h	(revision 18749)
@@ -0,0 +1,44 @@
+/** @file  psThread.h
+ *
+ *  @brief tools to manage a pool of threads
+ *
+ *  @author EAM, IFA
+ *  @version $Revision: 1.1.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2008-07-26 03:48:39 $
+ *
+ *  Copyright 2004-2005 Insitute for Astronomy, University of Hawaii
+ */
+
+#ifndef PS_THREAD_H
+#define PS_THREAD_H
+
+/// @addtogroup SysUtils System Utilities
+/// @{
+
+typedef struct {
+    psString type;
+    psArray *args;
+} psThreadJob;
+
+typedef struct {
+    bool busy;
+    bool fault;
+    pthread_t pt;
+} psThread;
+
+typedef void *(*psThreadLaunchJobsFunction)(void *data);
+
+void psThreadLock ();
+void psThreadUnlock ();
+
+psThreadJob *psThreadJobAlloc (char *type, int nArgs);
+bool psThreadJobAddToQueue (psThreadJob *job);
+psThreadJob *psThreadJobGet ();
+
+psThread *psThreadAlloc ();
+
+bool psThreadPoolInit (int nThreads, psThreadLaunchJobsFunction function);
+bool psThreadPoolWait ();
+
+/// @}
+#endif /* PS_THREAD_H */
