Example #1
0
int main(int argc, char **argv) {
	/* Slave threads */
	sgcomm_thread *st_rd; // Reader
	sgcomm_thread *st_tx; // Transmitter
	shared_buffer *sbtx; // shared buffer for read+transmit
	
	/* Reader message parameters */
	char *fmtstr = "/mnt/disks/%u/%u/data/%s";
	char *pattern_read = "input.vdif";
	char *host = "localhost";
	uint16_t port = 61234;
	int n_mod = 4;
	int mod_list[4] = { 1, 2, 3, 4};
	int n_disk = 8;
	int disk_list_read[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
	int disk_list_write[8] = { 1, 0, 2, 3, 4, 5, 6, 7 };
	
	/* Transmitter message parameters */
	if (argc > 1)
		pattern_read = argv[1];
	if (argc > 2)
		fmtstr = argv[2];
	if (argc > 3)
		host = argv[3];
	if (argc > 4)
		port = atoi(argv[4]);
	
	log_message(RL_NOTICE,"%s:Using input file '%s' matching pattern '%s'",__FUNCTION__,pattern_read,fmtstr);
	log_message(RL_NOTICE,"%s:Transmitting to %s:%u",__FUNCTION__,host,port);
	
	/* This thread */
	sgcomm_thread *st = &st_main;
	ctrl_state state;
	
	log_message(RL_DEBUG,"%s:Creating shared buffer",__FUNCTION__);
	
	/* Initialize shared data buffer */
	sbtx = create_shared_buffer(SHARED_BUFFER_SIZE_TX);
	if (sbtx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Creating slave threads",__FUNCTION__);
	
	/* Create thread instances */
	st_rd = create_thread(TT_READER);
	if (st_rd == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create reader thread",__FUNCTION__,__LINE__);
	st_tx = create_thread(TT_TRANSMITTER);
	if (st_tx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create transmitter thread",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Initializing thread messages",__FUNCTION__);
	
	/* Initialize thread messages */
	init_reader_msg((reader_msg *)st_rd->type_msg, sbtx, pattern_read, fmtstr,
					mod_list, n_mod, disk_list_read, n_disk);
	init_transmitter_msg((transmitter_msg *)st_tx->type_msg, sbtx,
					host, port);
	
	/* Start transmitter thread */
	if (start_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot start transmitter thread",__FUNCTION__,__LINE__);
	/* Pause, then see if transmitter has error, if so, abort */
	usleep(MAIN_WAIT_PERIOD_US);
	if ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) {
		set_thread_state(st,CS_ERROR,"%s(%d):Transmitter terminated prematurely, aborting start.",__FUNCTION__,__LINE__);
	} else {
		if (start_thread(st_rd) != 0)
			set_thread_state(st,CS_ERROR,"%s(%d):Cannot start reader thread",__FUNCTION__,__LINE__);
	}
	
	//~ log_message(RL_DEBUG,"%s:Entering main thread run loop",__FUNCTION__);
	
	if ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP))
		set_thread_state(st,CS_RUN,"%s:Thread running",__FUNCTION__);
	while ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP)) {
				
		// TODO: do something
		
		usleep(MAIN_WAIT_PERIOD_US);
		
		/* If any thread has a problem, stop all of them */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_ERROR)) ||
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_ERROR)) ) {
			// TODO: Some cleanup?
			break;
		}
		
		/* If all threads are stopped, break */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP)) &&
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) ) {
			log_message(RL_NOTICE,"%s:All threads stopped of their own volition",__FUNCTION__);
			break;
		}
		
		/* If reader thread is done, stop transmitter */
		if ( (get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP) && 
			 (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP)) {
			log_message(RL_NOTICE,"%s:Reader is done, stop transmitter",__FUNCTION__);
			/* Two wait periods should be enough - reader is the only
			 * other thread that can cause transmitter to wait on a 
			 * resource, and then it will only be a single wait. */
			usleep(MAIN_WAIT_PERIOD_US);
			usleep(MAIN_WAIT_PERIOD_US);
			if (stop_thread(st_tx) != 0)
				set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
		}
		
	}
	
	log_message(RL_DEBUG,"%s:Stopping slave threads",__FUNCTION__);
	
	/* Stop slave threads on tx side */
	if ( (get_thread_state(st_rd,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_rd) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop reader thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Reader thread stopped",__FUNCTION__);
	if ( (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Transmitter thread stopped",__FUNCTION__);
	
	log_message(RL_DEBUG,"%s:Destroying shared buffer",__FUNCTION__);
	
	/* Destroy shared data buffer */
	if (destroy_shared_buffer(&sbtx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot destroy shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Destroying slave threads",__FUNCTION__);
	
	/* Destroy threads */
	destroy_thread(&st_rd);
	destroy_thread(&st_tx);
	
	log_message(RL_DEBUG,"%s:Everything is done, goodbye",__FUNCTION__);
	
	/* That's all folks! */
	// TODO: Report that we're done
	return EXIT_SUCCESS;
}
Example #2
0
File: main.c Project: asdr/PCA
int main ( int argc, char** argv ) {
  FILE* pipe;
  SHAREDBUFFER* shared_buffer;
  CONFIG* config;
  char main_process_lifetime[15];
  int producer_count = 0;
  char producer_lifetime[15];
  int consumer_count = 0;
  int child_exit_status = 0;
  int child_exit_pid;
  int child_pid;
  int i = 0;
  int logfd;
  char message[150];
  char dir[255];
  int available_process_count = 10000;

  strncpy(dir, argv[0], last_index_of(argv[0], '/'));
  chdir(dir);

  logfd = log_open_file( NULL );
  if ( !logfd )
    {
      printf("Unable to open log file.\n");
      return EXIT_FAILURE;
    }

  log_event( "--------------------------------" );
  log_event( "Main process started." );

  // first of all load configuration file
  config = load_config_file();

  if ( !config )
    {
      log_event( "Unable to access configuration." );
      return EXIT_FAILURE;
    }

  // read values from configuration
  producer_count = atoi(read_configuration(config, "producer_count", "5"));
  consumer_count = atoi(read_configuration(config, "consumer_count", "2"));
  strcpy(producer_lifetime, read_configuration(config, "producer_lifetime", "10"));
  strcpy(main_process_lifetime, read_configuration(config, "main_process_lifetime", "40"));

  destroy_config( config );

  log_event( "Fetching available process count of system." );
  pipe = popen(PROCESS_COUNT_SCRIPT, "r");
  if ( pipe )
    {
      fgets(message, 100, pipe);
      pclose(pipe);
      available_process_count = atoi(message);
    }

  if ( producer_count + consumer_count + 1 > available_process_count )
    {
      log_event( "Requested total process count is more than available process count of system." );
      goto SAFE_EXIT;
    }

  //initialize shared buffer
  shared_buffer = create_shared_buffer();

  if ( !shared_buffer )
    {
      log_event( "Unable to initialize shared buffer." );
      destroy_config( config );
      return EXIT_FAILURE;
    }

  // create and start producer processes
  // producer processes run for a specified lifetime ( in seconds )
  // which is read from configuration
  for ( i=0; i<producer_count; ++i)
    {
      child_pid = vfork();
      if ( child_pid == 0 ) // producer process
        {
          execl("producer", "producer", producer_lifetime, NULL);
          exit(0);
        }
    }

  // start consumer processes
  // consumer processes run until a SIGKILL signal
  // there is no specific entry in the requirements that
  // when a consumer process should end.
  for ( i=0; i<consumer_count; ++i)
    {
      child_pid = vfork();
      if ( child_pid == 0 ) // consumer process
        {
          execl("consumer", "consumer", NULL);
          exit(0);
        }
    }

  // start controller process
  // controller process checks elapsed time
  // once in every 5 seconds
  // if total execution time is above a specified time (in seconds)
  // signals all child processes except itself, to force exit
  child_pid = vfork();
  if ( child_pid == 0 ) //controller process
    {
      execl("controller", "controller", main_process_lifetime, NULL);
      exit(0);
    }

  // in order to catch all child processes exits
  // we need a common wait for all them
  // here exitting processes is cought with pid and exit status
  // wait childs to exit
  while( (child_exit_pid = wait(&child_exit_status)) > 0 )
    {
      sprintf( message, "Process [PID:%d] exitid with status: %d", child_exit_pid, child_exit_status );
      log_event( message );
    }

 SAFE_EXIT:
  log_event( "Main process is being closed." );

  // relase allocated data structures to OS
  destroy_shared_buffer( shared_buffer );

  log_close_file(  );

  return EXIT_SUCCESS;
}