ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
starter.c
Go to the documentation of this file.
1
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
41static int nThreadsRunning = 0;
42
43// mutext to control access to the number of threads
44pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
45
46// procedure for duplicating strings
47char * Abc_UtilStrsav( char * s ) { return s ? strcpy(malloc(strlen(s)+1), s) : NULL; }
48
60void * 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);
75 nThreadsRunning--;
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
97int 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);
139 Counter = nThreadsRunning;
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);
164 Counter = nThreadsRunning;
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
178usage:
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
usage()
Definition main.c:626
int main(int argc, char *argv[])
GLOBAL VARIABLES ///.
Definition starter.c:97
#define MAX_COMM_NUM
Definition starter.c:35
#define ABC_PRT(a, t)
Definition starter.c:38
void * Abc_RunThread(void *Command)
Definition starter.c:60
char * Abc_UtilStrsav(char *s)
Definition starter.c:47
pthread_mutex_t mutex
Definition starter.c:44
#define assert(ex)
Definition util_old.h:213
int strlen()
int system()
char * strcpy()
VOID_HACK free()
char * malloc()