summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/starter.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/starter.c b/src/starter.c
new file mode 100644
index 00000000..ce86d62b
--- /dev/null
+++ b/src/starter.c
@@ -0,0 +1,194 @@
+/**CFile****************************************************************
+
+ FileName [starter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Wrapper for calling ABC.]
+
+ Synopsis [A demo program illustrating parallel execution of ABC.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - October 22, 2009.]
+
+ Revision [$Id: starter.c,v 1.00 2009/10/22 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+// To compile on Linux run: gcc -pthread -o starter starter.c
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#ifdef WIN32
+#include "pthread.h"
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+//ABC_NAMESPACE_IMPL_START
+
+// the max number of commands to execute from the input file
+#define MAX_COMM_NUM 1000
+
+// time printing
+#define ABC_PRT(a,t) (printf("%s = ", (a)), printf("%7.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC)))
+
+// the number of currently running threads
+static int nThreadsRunning = 0;
+
+// mutext to control access to the number of threads
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// procedure for duplicating strings
+char * Abc_UtilStrsav( char * s ) { return s ? strcpy(malloc(strlen(s)+1), s) : NULL; }
+
+/**Function*************************************************************
+
+ Synopsis [This procedures executes one call to system().]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_RunThread( void * Command )
+{
+ // perform the call
+ if ( system( (char *)Command ) )
+ {
+ assert(pthread_mutex_lock(&mutex) == 0);
+ fprintf( stderr, "The following command has returned non-zero exit status:\n" );
+ fprintf( stderr, "\"%s\"\n", (char *)Command );
+ fprintf( stderr, "Sorry for the inconvenience.\n" );
+ fflush( stdout );
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ }
+
+ // decrement the number of threads runining
+ assert(pthread_mutex_lock(&mutex) == 0);
+ nThreadsRunning--;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ // quit this thread
+ //printf("...Finishing %s\n", (char *)Command);
+ free( Command );
+ pthread_exit( NULL );
+ assert(0);
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Takes file with commands to be executed and the number of CPUs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int main( int argc, char * argv[] )
+{
+ FILE * pFile, * pOutput = stdout;
+ pthread_t ThreadIds[MAX_COMM_NUM];
+ char * pBufferCopy, Buffer[MAX_COMM_NUM];
+ int i, nCPUs = 0, nLines = 0, Counter;
+ clock_t clk = clock();
+
+ // check command line arguments
+ if ( argc != 3 )
+ { fprintf( stderr, "Wrong number of command line arguments.\n" ); goto usage; }
+
+ // get the number of CPUs
+ nCPUs = atoi( argv[1] );
+ if ( nCPUs <= 0 )
+ { fprintf( pOutput, "Cannot read an integer represting the number of CPUs.\n" ); goto usage; }
+
+ // open the file and make sure it is available
+ pFile = fopen( argv[2], "r" );
+ if ( pFile == NULL )
+ { fprintf( pOutput, "Input file \"%s\" cannot be opened.\n", argv[2] ); goto usage; }
+
+ // read commands and execute at most <num> of them at a time
+// assert(mutex == PTHREAD_MUTEX_INITIALIZER);
+ while ( fgets( Buffer, MAX_COMM_NUM, pFile ) != NULL )
+ {
+ // get the command from the file
+ if ( Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' ||
+ Buffer[0] == ' ' || Buffer[0] == '#')
+ {
+ continue;
+ }
+
+ if ( Buffer[strlen(Buffer)-1] == '\n' )
+ Buffer[strlen(Buffer)-1] = 0;
+ if ( Buffer[strlen(Buffer)-1] == '\r' )
+ Buffer[strlen(Buffer)-1] = 0;
+
+ // wait till there is an empty thread
+ while ( 1 )
+ {
+ assert(pthread_mutex_lock(&mutex) == 0);
+ Counter = nThreadsRunning;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ if ( Counter < nCPUs - 1 )
+ break;
+// Sleep( 100 );
+ }
+
+ // increament the number of threads running
+ assert(pthread_mutex_lock(&mutex) == 0);
+ nThreadsRunning++;
+ printf( "Calling: %s\n", (char *)Buffer );
+ fflush( stdout );
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ // create thread to execute this command
+ pBufferCopy = Abc_UtilStrsav( Buffer );
+ assert(pthread_create( &ThreadIds[nLines], NULL, Abc_RunThread, (void *)pBufferCopy ) == 0);
+ if ( ++nLines == MAX_COMM_NUM )
+ { fprintf( pOutput, "Cannot execute more than %d commands from file \"%s\".\n", nLines, argv[2] ); break; }
+ }
+
+ // wait for all the threads to finish
+ while ( 1 )
+ {
+ assert(pthread_mutex_lock(&mutex) == 0);
+ Counter = nThreadsRunning;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ if ( Counter == 0 )
+ break;
+ }
+
+ // cleanup
+ assert(pthread_mutex_destroy(&mutex) == 0);
+// assert(mutex == NULL);
+ fclose( pFile );
+ printf( "Finished processing commands in file \"%s\". ", argv[2] );
+ ABC_PRT( "Total time", clock() - clk );
+ return 0;
+
+usage:
+ // skip the path name till the binary name
+ for ( i = strlen(argv[0]) - 1; i > 0; i-- )
+ if ( argv[0][i-1] == '\\' || argv[0][i-1] == '/' )
+ break;
+ // print usage message
+ fprintf( pOutput, "usage: %s <num> <file>\n", argv[0]+i );
+ fprintf( pOutput, " executes command listed in <file> in parallel on <num> CPUs\n" );
+ fprintf( pOutput, "\n" );
+ return 1;
+
+}
+
+//ABC_NAMESPACE_IMPL_END
+