abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
starter.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [starter.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Wrapper for calling ABC.]
8 
9  Synopsis [A demo program illustrating parallel execution of ABC.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - October 22, 2009.]
16 
17  Revision [$Id: starter.c,v 1.00 2009/10/22 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 // To compile on Linux run: gcc -pthread -o starter starter.c
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #ifdef WIN32
28 #include "pthread.h"
29 #else
30 #include <pthread.h>
31 #include <unistd.h>
32 #endif
33 
34 // the max number of commands to execute from the input file
35 #define MAX_COMM_NUM 1000
36 
37 // time printing
38 #define ABC_PRT(a,t) (printf("%s = ", (a)), printf("%7.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC)))
39 
40 // the number of currently running threads
41 static int nThreadsRunning = 0;
42 
43 // mutext to control access to the number of threads
44 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
45 
46 // procedure for duplicating strings
47 char * Abc_UtilStrsav( char * s ) { return s ? strcpy(malloc(strlen(s)+1), s) : NULL; }
48 
49 /**Function*************************************************************
50 
51  Synopsis [This procedures executes one call to system().]
52 
53  Description []
54 
55  SideEffects []
56 
57  SeeAlso []
58 
59 ***********************************************************************/
60 void * Abc_RunThread( void * Command )
61 {
62  // perform the call
63  if ( system( (char *)Command ) )
64  {
65  assert(pthread_mutex_lock(&mutex) == 0);
66  fprintf( stderr, "The following command has returned non-zero exit status:\n" );
67  fprintf( stderr, "\"%s\"\n", (char *)Command );
68  fprintf( stderr, "Sorry for the inconvenience.\n" );
69  fflush( stdout );
70  assert(pthread_mutex_unlock(&mutex) == 0);
71  }
72 
73  // decrement the number of threads runining
74  assert(pthread_mutex_lock(&mutex) == 0);
76  assert(pthread_mutex_unlock(&mutex) == 0);
77 
78  // quit this thread
79  //printf("...Finishing %s\n", (char *)Command);
80  free( Command );
81  pthread_exit( NULL );
82  assert(0);
83  return NULL;
84 }
85 
86 /**Function*************************************************************
87 
88  Synopsis [Takes file with commands to be executed and the number of CPUs.]
89 
90  Description []
91 
92  SideEffects []
93 
94  SeeAlso []
95 
96 ***********************************************************************/
97 int main( int argc, char * argv[] )
98 {
99  FILE * pFile, * pOutput = stdout;
100  pthread_t ThreadIds[MAX_COMM_NUM];
101  char * pBufferCopy, Buffer[MAX_COMM_NUM];
102  int i, nCPUs = 0, nLines = 0, Counter;
103  clock_t clk = clock();
104 
105  // check command line arguments
106  if ( argc != 3 )
107  { fprintf( stderr, "Wrong number of command line arguments.\n" ); goto usage; }
108 
109  // get the number of CPUs
110  nCPUs = atoi( argv[1] );
111  if ( nCPUs <= 0 )
112  { fprintf( pOutput, "Cannot read an integer represting the number of CPUs.\n" ); goto usage; }
113 
114  // open the file and make sure it is available
115  pFile = fopen( argv[2], "r" );
116  if ( pFile == NULL )
117  { fprintf( pOutput, "Input file \"%s\" cannot be opened.\n", argv[2] ); goto usage; }
118 
119  // read commands and execute at most <num> of them at a time
120 // assert(mutex == PTHREAD_MUTEX_INITIALIZER);
121  while ( fgets( Buffer, MAX_COMM_NUM, pFile ) != NULL )
122  {
123  // get the command from the file
124  if ( Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' ||
125  Buffer[0] == ' ' || Buffer[0] == '#')
126  {
127  continue;
128  }
129 
130  if ( Buffer[strlen(Buffer)-1] == '\n' )
131  Buffer[strlen(Buffer)-1] = 0;
132  if ( Buffer[strlen(Buffer)-1] == '\r' )
133  Buffer[strlen(Buffer)-1] = 0;
134 
135  // wait till there is an empty thread
136  while ( 1 )
137  {
138  assert(pthread_mutex_lock(&mutex) == 0);
140  assert(pthread_mutex_unlock(&mutex) == 0);
141  if ( Counter < nCPUs - 1 )
142  break;
143 // Sleep( 100 );
144  }
145 
146  // increament the number of threads running
147  assert(pthread_mutex_lock(&mutex) == 0);
148  nThreadsRunning++;
149  printf( "Calling: %s\n", (char *)Buffer );
150  fflush( stdout );
151  assert(pthread_mutex_unlock(&mutex) == 0);
152 
153  // create thread to execute this command
154  pBufferCopy = Abc_UtilStrsav( Buffer );
155  assert(pthread_create( &ThreadIds[nLines], NULL, Abc_RunThread, (void *)pBufferCopy ) == 0);
156  if ( ++nLines == MAX_COMM_NUM )
157  { fprintf( pOutput, "Cannot execute more than %d commands from file \"%s\".\n", nLines, argv[2] ); break; }
158  }
159 
160  // wait for all the threads to finish
161  while ( 1 )
162  {
163  assert(pthread_mutex_lock(&mutex) == 0);
165  assert(pthread_mutex_unlock(&mutex) == 0);
166  if ( Counter == 0 )
167  break;
168  }
169 
170  // cleanup
171  assert(pthread_mutex_destroy(&mutex) == 0);
172 // assert(mutex == NULL);
173  fclose( pFile );
174  printf( "Finished processing commands in file \"%s\". ", argv[2] );
175  ABC_PRT( "Total time", clock() - clk );
176  return 0;
177 
178 usage:
179  // skip the path name till the binary name
180  for ( i = strlen(argv[0]) - 1; i > 0; i-- )
181  if ( argv[0][i-1] == '\\' || argv[0][i-1] == '/' )
182  break;
183  // print usage message
184  fprintf( pOutput, "usage: %s <num> <file>\n", argv[0]+i );
185  fprintf( pOutput, " executes command listed in <file> in parallel on <num> CPUs\n" );
186  fprintf( pOutput, "\n" );
187  return 1;
188 
189 }
190 
static int nThreadsRunning
Definition: starter.c:41
char * malloc()
#define MAX_COMM_NUM
Definition: starter.c:35
VOID_HACK free()
#define ABC_PRT(a, t)
Definition: starter.c:38
pthread_mutex_t mutex
Definition: starter.c:44
void * Abc_RunThread(void *Command)
Definition: starter.c:60
static int Counter
int system()
char * strcpy()
#define assert(ex)
Definition: util_old.h:213
int strlen()
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
int main(int argc, char *argv[])
GLOBAL VARIABLES ///.
Definition: starter.c:97