abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cmdStarter.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [cmdStarter.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Command processing package.]
8 
9  Synopsis [Command to start many instances of ABC in parallel.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: cmdStarter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "misc/util/abc_global.h"
26 #include "misc/extra/extra.h"
27 
28 #ifdef ABC_USE_PTHREADS
29 
30 #ifdef _WIN32
31 #include "../lib/pthread.h"
32 #else
33 #include <pthread.h>
34 #include <unistd.h>
35 #endif
36 
37 #endif
38 
40 
41 ////////////////////////////////////////////////////////////////////////
42 /// DECLARATIONS ///
43 ////////////////////////////////////////////////////////////////////////
44 
45 #ifndef ABC_USE_PTHREADS
46 
47 void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores ) {}
48 
49 #else // pthreads are used
50 
51 // the number of concurrently running threads
52 static volatile int nThreadsRunning = 0;
53 
54 // mutex to control access to the number of threads
55 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
56 
57 ////////////////////////////////////////////////////////////////////////
58 /// FUNCTION DEFINITIONS ///
59 ////////////////////////////////////////////////////////////////////////
60 
61 /**Function*************************************************************
62 
63  Synopsis [This procedures executes one call to system().]
64 
65  Description []
66 
67  SideEffects []
68 
69  SeeAlso []
70 
71 ***********************************************************************/
72 void * Abc_RunThread( void * pCommand )
73 {
74  int status;
75  // perform the call
76  if ( system( (char *)pCommand ) )
77  {
78  fprintf( stderr, "The following command has returned non-zero exit status:\n" );
79  fprintf( stderr, "\"%s\"\n\n", (char *)pCommand );
80  fflush( stdout );
81  }
82  free( pCommand );
83 
84  // decrement the number of threads runining
85  status = pthread_mutex_lock(&mutex); assert(status == 0);
87  status = pthread_mutex_unlock(&mutex); assert(status == 0);
88 
89  // quit this thread
90  //printf("...Finishing %s\n", (char *)Command);
91  pthread_exit( NULL );
92  assert(0);
93  return NULL;
94 }
95 
96 /**Function*************************************************************
97 
98  Synopsis [Takes file with commands to be executed and the number of CPUs.]
99 
100  Description []
101 
102  SideEffects []
103 
104  SeeAlso []
105 
106 ***********************************************************************/
107 void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores )
108 {
109  FILE * pFile, * pFileTemp;
110  pthread_t * pThreadIds;
111  char * BufferCopy, * Buffer;
112  int nLines, LineMax, Line, Len;
113  int i, c, status, Counter;
114  abctime clk = Abc_Clock();
115 
116  // check the number of cores
117  if ( nCores < 2 )
118  {
119  fprintf( stdout, "The number of cores (%d) should be more than 1.\n", nCores );
120  return;
121  }
122 
123  // open the file and make sure it is available
124  pFile = fopen( pFileName, "rb" );
125  if ( pFile == NULL )
126  {
127  fprintf( stdout, "Input file \"%s\" cannot be opened.\n", pFileName );
128  return;
129  }
130 
131  // count the number of lines and the longest line
132  nLines = LineMax = Line = 0;
133  while ( (c = fgetc(pFile)) != EOF )
134  {
135  Line++;
136  if ( c != '\n' )
137  continue;
138  nLines++;
139  LineMax = Abc_MaxInt( LineMax, Line );
140  Line = 0;
141  }
142  nLines += 10;
143  LineMax += LineMax + 100;
144  LineMax += pBinary ? strlen(pBinary) : 0;
145  LineMax += pCommand ? strlen(pCommand) : 0;
146 
147  // allocate storage
148  Buffer = ABC_ALLOC( char, LineMax );
149  pThreadIds = ABC_ALLOC( pthread_t, nLines );
150 
151  // check if all files can be opened
152  if ( pCommand != NULL )
153  {
154  // read file names
155  rewind( pFile );
156  for ( i = 0; fgets( Buffer, LineMax, pFile ) != NULL; i++ )
157  {
158  // remove trailing spaces
159  for ( Len = strlen(Buffer) - 1; Len >= 0; Len-- )
160  if ( Buffer[Len] == '\n' || Buffer[Len] == '\r' || Buffer[Len] == '\t' || Buffer[Len] == ' ' )
161  Buffer[Len] = 0;
162  else
163  break;
164 
165  // get command from file
166  if ( Buffer[0] == 0 || Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || Buffer[0] == ' ' || Buffer[0] == '#' )
167  continue;
168 
169  // try to open the file
170  pFileTemp = fopen( Buffer, "rb" );
171  if ( pFileTemp == NULL )
172  {
173  fprintf( stdout, "Starter cannot open file \"%s\".\n", Buffer );
174  fflush( stdout );
175  ABC_FREE( pThreadIds );
176  ABC_FREE( Buffer );
177  fclose( pFile );
178  return;
179  }
180  }
181  }
182 
183  // read commands and execute at most <num> of them at a time
184  rewind( pFile );
185  for ( i = 0; fgets( Buffer, LineMax, pFile ) != NULL; i++ )
186  {
187  // remove trailing spaces
188  for ( Len = strlen(Buffer) - 1; Len >= 0; Len-- )
189  if ( Buffer[Len] == '\n' || Buffer[Len] == '\r' || Buffer[Len] == '\t' || Buffer[Len] == ' ' )
190  Buffer[Len] = 0;
191  else
192  break;
193 
194  // get command from file
195  if ( Buffer[0] == 0 || Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || Buffer[0] == ' ' || Buffer[0] == '#' )
196  continue;
197 
198  // create command
199  if ( pCommand != NULL )
200  {
201  BufferCopy = ABC_ALLOC( char, LineMax );
202  sprintf( BufferCopy, "%s -c \"%s; %s\" > %s", pBinary, Buffer, pCommand, Extra_FileNameGenericAppend(Buffer, ".txt") );
203  }
204  else
205  BufferCopy = Abc_UtilStrsav( Buffer );
206  fprintf( stdout, "Calling: %s\n", (char *)BufferCopy );
207  fflush( stdout );
208 
209  // wait till there is an empty thread
210  while ( 1 )
211  {
212  status = pthread_mutex_lock(&mutex); assert(status == 0);
213  Counter = nThreadsRunning;
214  status = pthread_mutex_unlock(&mutex); assert(status == 0);
215  if ( Counter < nCores - 1 )
216  break;
217 // Sleep( 100 );
218  }
219 
220  // increament the number of threads running
221  status = pthread_mutex_lock(&mutex); assert(status == 0);
222  nThreadsRunning++;
223  status = pthread_mutex_unlock(&mutex); assert(status == 0);
224 
225  // create thread to execute this command
226  status = pthread_create( &pThreadIds[i], NULL, Abc_RunThread, (void *)BufferCopy ); assert(status == 0);
227  assert( i < nLines );
228  }
229  ABC_FREE( pThreadIds );
230  ABC_FREE( Buffer );
231  fclose( pFile );
232 
233  // wait for all the threads to finish
234  while ( 1 )
235  {
236  status = pthread_mutex_lock(&mutex); assert(status == 0);
237  Counter = nThreadsRunning;
238  status = pthread_mutex_unlock(&mutex); assert(status == 0);
239  if ( Counter == 0 )
240  break;
241  }
242 
243  // cleanup
244 // status = pthread_mutex_destroy(&mutex); assert(status == 0);
245 // mutex = PTHREAD_MUTEX_INITIALIZER;
246  fprintf( stdout, "Finished processing commands in file \"%s\". ", pFileName );
247  Abc_PrintTime( 1, "Total wall time", Abc_Clock() - clk );
248  fflush( stdout );
249 }
250 
251 #endif // pthreads are used
252 
253 ////////////////////////////////////////////////////////////////////////
254 /// END OF FILE ///
255 ////////////////////////////////////////////////////////////////////////
256 
257 
259 
static int nThreadsRunning
Definition: starter.c:41
VOID_HACK free()
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static abctime Abc_Clock()
Definition: abc_global.h:279
static int Abc_MaxInt(int a, int b)
Definition: abc_global.h:238
ABC_NAMESPACE_IMPL_START void Cmd_RunStarter(char *pFileName, char *pBinary, char *pCommand, int nCores)
DECLARATIONS ///.
Definition: cmdStarter.c:47
pthread_mutex_t mutex
Definition: starter.c:44
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
void * Abc_RunThread(void *Command)
Definition: starter.c:60
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define Len
Definition: deflate.h:78
char * sprintf()
static int Counter
int system()
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define assert(ex)
Definition: util_old.h:213
char * Extra_FileNameGenericAppend(char *pBase, char *pSuffix)
int strlen()
ABC_INT64_T abctime
Definition: abc_global.h:278
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
VOID_HACK rewind()