cmdStarter.c 7.78 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/**CFile****************************************************************

  FileName    [cmdStarter.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Command processing package.]

  Synopsis    [Command to start many instances of ABC in parallel.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: cmdStarter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "misc/util/abc_global.h"
26
#include "misc/extra/extra.h"
27 28 29

#ifdef ABC_USE_PTHREADS

30
#ifdef _WIN32
31 32 33 34 35 36 37 38 39
#include "../lib/pthread.h"
#else
#include <pthread.h>
#include <unistd.h>
#endif

#endif

ABC_NAMESPACE_IMPL_START
40
 
41 42 43 44 45 46
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

#ifndef ABC_USE_PTHREADS

47
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores ) {}
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

#else // pthreads are used

// the number of concurrently running threads
static volatile int nThreadsRunning = 0;

// mutex to control access to the number of threads
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [This procedures executes one call to system().]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void * Abc_RunThread( void * pCommand )
{
    int status;
    // perform the call
    if ( system( (char *)pCommand ) )
    {
        fprintf( stderr, "The following command has returned non-zero exit status:\n" );
        fprintf( stderr, "\"%s\"\n\n", (char *)pCommand );
        fflush( stdout );
    }
    free( pCommand );

    // decrement the number of threads runining 
    status = pthread_mutex_lock(&mutex);   assert(status == 0);
    nThreadsRunning--;
    status = pthread_mutex_unlock(&mutex); assert(status == 0);

    // quit this thread
    //printf("...Finishing %s\n", (char *)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     []

***********************************************************************/
107
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores )
108
{
109
    FILE * pFile, * pFileTemp;
110 111
    pthread_t * pThreadIds;
    char * BufferCopy, * Buffer;
112
    int nLines, LineMax, Line, Len;
113
    int i, c, status, Counter;
114
    abctime clk = Abc_Clock();
115 116 117 118

    // check the number of cores
    if ( nCores < 2 )
    {
119
        fprintf( stdout, "The number of cores (%d) should be more than 1.\n", nCores ); 
120 121 122 123 124 125 126
        return; 
    }

    // open the file and make sure it is available
    pFile = fopen( pFileName, "rb" );
    if ( pFile == NULL )
    { 
127
        fprintf( stdout, "Input file \"%s\" cannot be opened.\n", pFileName ); 
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
        return; 
    }

    // count the number of lines and the longest line
    nLines = LineMax = Line = 0;
    while ( (c = fgetc(pFile)) != EOF )
    {
        Line++;
        if ( c != '\n' )
            continue;
        nLines++;
        LineMax = Abc_MaxInt( LineMax, Line );
        Line = 0;       
    }
    nLines += 10;
143 144 145
    LineMax += LineMax + 100;
    LineMax += pBinary  ? strlen(pBinary) : 0;
    LineMax += pCommand ? strlen(pCommand) : 0;
146 147 148 149 150

    // allocate storage
    Buffer = ABC_ALLOC( char, LineMax );
    pThreadIds = ABC_ALLOC( pthread_t, nLines );

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    // check if all files can be opened
    if ( pCommand != NULL )
    {
        // read file names
        rewind( pFile );
        for ( i = 0; fgets( Buffer, LineMax, pFile ) != NULL; i++ )
        {
            // remove trailing spaces
            for ( Len = strlen(Buffer) - 1; Len >= 0; Len-- )
                if ( Buffer[Len] == '\n' || Buffer[Len] == '\r' || Buffer[Len] == '\t' || Buffer[Len] == ' ' )
                    Buffer[Len] = 0;
                else
                    break;

            // get command from file
            if ( Buffer[0] == 0 || Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || Buffer[0] == ' ' || Buffer[0] == '#' )
                continue;

            // try to open the file
            pFileTemp = fopen( Buffer, "rb" );
            if ( pFileTemp == NULL )
            {
                fprintf( stdout, "Starter cannot open file \"%s\".\n", Buffer );
                fflush( stdout );
                ABC_FREE( pThreadIds );
                ABC_FREE( Buffer );
                fclose( pFile );
                return;
            }    
        }
    } 
 
183 184 185 186
    // read commands and execute at most <num> of them at a time
    rewind( pFile );
    for ( i = 0; fgets( Buffer, LineMax, pFile ) != NULL; i++ )
    {
187 188 189 190 191 192 193 194 195
        // remove trailing spaces
        for ( Len = strlen(Buffer) - 1; Len >= 0; Len-- )
            if ( Buffer[Len] == '\n' || Buffer[Len] == '\r' || Buffer[Len] == '\t' || Buffer[Len] == ' ' )
                Buffer[Len] = 0;
            else
                break;

        // get command from file
        if ( Buffer[0] == 0 || Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || Buffer[0] == ' ' || Buffer[0] == '#' )
196 197
            continue;

198 199 200 201 202 203 204 205 206 207
        // create command
        if ( pCommand != NULL )
        {
            BufferCopy = ABC_ALLOC( char, LineMax );
            sprintf( BufferCopy, "%s -c \"%s; %s\" > %s", pBinary, Buffer, pCommand, Extra_FileNameGenericAppend(Buffer, ".txt") );
        }
        else
            BufferCopy = Abc_UtilStrsav( Buffer );
        fprintf( stdout, "Calling:  %s\n", (char *)BufferCopy );  
        fflush( stdout );
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

        // wait till there is an empty thread
        while ( 1 )
        {
            status = pthread_mutex_lock(&mutex);   assert(status == 0);
            Counter = nThreadsRunning;
            status = pthread_mutex_unlock(&mutex); assert(status == 0);
            if ( Counter < nCores - 1 )
                break;
//            Sleep( 100 );
        }

        // increament the number of threads running
        status = pthread_mutex_lock(&mutex);   assert(status == 0);
        nThreadsRunning++;
        status = pthread_mutex_unlock(&mutex); assert(status == 0);

        // create thread to execute this command
        status = pthread_create( &pThreadIds[i], NULL, Abc_RunThread, (void *)BufferCopy );  assert(status == 0);
        assert( i < nLines );
    }
    ABC_FREE( pThreadIds );
    ABC_FREE( Buffer );
    fclose( pFile );

    // wait for all the threads to finish
    while ( 1 )
    {
        status = pthread_mutex_lock(&mutex);   assert(status == 0);
        Counter = nThreadsRunning;
        status = pthread_mutex_unlock(&mutex); assert(status == 0);
        if ( Counter == 0 )
            break;
    }

    // cleanup
244 245
//    status = pthread_mutex_destroy(&mutex);   assert(status == 0);
//    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 255 256 257 258 259

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END