Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2015
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. #include <divine.h>
  2. #include <divine/problem.h>
  3. #include <mpi.h>
  4. #include <cstdlib>
  5.  
  6. // TODO desc: this is expected to be set in model (__attribute__((constructor)))
  7. // if desired
  8. int _mpi_num_processes = 0;
  9. int _mpi_enable_mpi_comm_self = false;
  10.  
  11. int _mpi_exit_barrier = 0;
  12.  
  13. extern "C" {
  14.     int main(...);
  15.     struct global_ctor { int prio; void (*fn)(); };
  16.  
  17.     int _divine_invoke_main( int mainproto )
  18.     {
  19.         int r;
  20.         switch ( mainproto ) {
  21.             case 0: r = main(); break;
  22.             case 1: r = main( 0 ); break;
  23.             case 2: r = main( 0, 0 ); break;
  24.             case 3: r = main( 0, 0, 0 ); break;
  25.             default: __divine_problem( 1, "don't know how to run main()" );
  26.         }
  27.         return r;
  28.     }
  29.  
  30.     void _divine_invoke_main_mpi( void *mainproto )
  31.     {
  32.         // run main
  33.         int r = _divine_invoke_main( *((int *) mainproto) );
  34.  
  35.         // check whether MPI_Finalize has been called
  36.         int finalized; MPI_Finalized( &finalized );
  37.         if ( !finalized ) {
  38.             __divine_problem( Other,
  39.                     "MPI_Finalize not called before program termination" );
  40.         }
  41.  
  42.         // synchronize thread exits because it's needed apparently TODO desc
  43.         __divine_interrupt_mask();
  44.         ++_mpi_exit_barrier;
  45.  
  46.         while ( !(_mpi_exit_barrier == _mpi_num_processes &&
  47.                 __divine_get_tid() == 0) ) {
  48.             __divine_interrupt_unmask();
  49.             __divine_interrupt_mask();
  50.         }
  51.  
  52.         exit( r ); // only thread 0 gets here
  53.     }
  54.  
  55.     void _divine_start( int ctorcount, void *ctors, int mainproto )
  56.     {
  57.         __divine_interrupt_mask(); //FIXME remove
  58.         global_ctor *c = reinterpret_cast< global_ctor * >( ctors );
  59.         for ( int i = 0; i < ctorcount; ++i ) {
  60.             c->fn();
  61.             c ++;
  62.         }
  63.         __divine_interrupt_unmask(); //FIXME remove
  64.  
  65.         if ( _mpi_num_processes == 0 ) {
  66.             // normal startup (no MPI): run main in one thread
  67.             int r = _divine_invoke_main( mainproto );
  68.             exit( r );
  69.         } else {
  70.             // MPI startup: run main in the specified number of threads
  71.             // (emulating MPI processes)
  72.             __divine_interrupt_mask();
  73.  
  74.             for ( int i = 0; i < _mpi_num_processes - 1; ++i ) {
  75.                 __divine_new_thread( _divine_invoke_main_mpi,
  76.                         (void *) &mainproto );
  77.             }
  78.  
  79.             // global MPI initialization is run after the process threads have
  80.             // been started, but before they actually had a chance to run
  81.             // (ensured by interrupt masking); this is done in order to preserve
  82.             // sequential numbering of the process threads, since one other
  83.             // thread (the message daemon of MPI_COMM_WORLD) is created as a
  84.             // part of the initialization
  85.             _divine_mpi_global_initialize();
  86.             __divine_interrupt_unmask();
  87.  
  88.             _divine_invoke_main_mpi( (void *) &mainproto );
  89.         }
  90.     }
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement