示例#1
0
int main(int argc, char **argv) {

#ifdef RTAI
  RT_TASK *task;
  RTIME period;
#endif
  int i,j,aa;
  void *status;

  /*
  uint32_t rf_mode_max[4]     = {55759,55759,55759,55759};
  uint32_t rf_mode_med[4]     = {39375,39375,39375,39375};
  uint32_t rf_mode_byp[4]     = {22991,22991,22991,22991};
  */
  uint32_t my_rf_mode = RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX;
  uint32_t rf_mode_base = TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM;
  uint32_t rf_mode[4]     = {my_rf_mode,0,0,0};
  uint32_t rf_local[4]    = {8255000,8255000,8255000,8255000}; // UE zepto
    //{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
    //{8255067,8254810,8257340,8257340}; // eNB PETRONAS

  uint32_t rf_vcocal[4]   = {910,910,910,910};
  uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015};
  uint32_t rf_rxdc[4]     = {32896,32896,32896,32896};
  uint32_t rxgain[4]      = {20,20,20,20};
  uint32_t txgain[4]      = {20,20,20,20};

  uint16_t Nid_cell = 0;
  uint8_t  cooperation_flag=0, transmission_mode=1, abstraction_flag=0;
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;

  int c;
  char do_forms=0;
  unsigned int fd;
  unsigned int tcxo = 114;

  int amp;
  uint8_t prach_fmt;
  int N_ZC;

  char rxg_fname[100];
  char txg_fname[100];
  char rflo_fname[100];
  char rfdc_fname[100];
  FILE *rxg_fd=NULL;
  FILE *txg_fd=NULL;
  FILE *rflo_fd=NULL;
  FILE *rfdc_fd=NULL;
  unsigned int rxg_max[4]={133,133,133,133}, rxg_med[4]={127,127,127,127}, rxg_byp[4]={120,120,120,120};
  int tx_max_power=0;

  char line[1000];
  int l;
  int ret, ant;
  int ant_offset=0;

  int error_code;
  char *itti_dump_file = NULL;

  const struct option long_options[] = {
    {"calib-ue-rx", required_argument, NULL, 256},
    {"calib-ue-rx-med", required_argument, NULL, 257},
    {"calib-ue-rx-byp", required_argument, NULL, 258},
    {"debug-ue-prach", no_argument, NULL, 259},
    {"no-L2-connect", no_argument, NULL, 260},
    {NULL, 0, NULL, 0}};

  //mode = normal_txrx;


  while ((c = getopt_long (argc, argv, "C:K:O:ST:UdF:V",long_options,NULL)) != -1)
    {
      switch (c)
        {
	case 'V':
          ouput_vcd = 1;
	  break;
        case 'd':
          do_forms=1;
          break;
        case 'U':
          UE_flag = 1;
          break;
        case 'C':
          carrier_freq[0] = atoi(optarg);
          carrier_freq[1] = atoi(optarg);
          carrier_freq[2] = atoi(optarg);
          carrier_freq[3] = atoi(optarg);
          break;
        case 'S':
          fs4_test=1;
          break;
        case 'T':
          tcxo=atoi(optarg);
          break;
        case 'K':
#if defined(ENABLE_ITTI)
          itti_dump_file = strdup(optarg);
#else
          printf("-K option is disabled when ENABLE_ITTI is not defined\n");
#endif
          break;
        case 'O':
#if defined(ENABLE_USE_MME)
          EPC_MODE_ENABLED = 1;
          if (optarg == NULL) /* No IP address provided: use localhost */
          {
            memcpy(&EPC_MODE_MME_ADDRESS[0], "127.0.0.1", 10);
          } else {
            uint8_t ip_length = strlen(optarg) + 1;
            memcpy(&EPC_MODE_MME_ADDRESS[0], optarg,
            ip_length > 16 ? 16 : ip_length);
          }
#else
          printf("You enabled mme mode without s1ap compiled...\n");
#endif
          break;
	case 'F':
	  sprintf(rxg_fname,"%srxg.lime",optarg);
	  rxg_fd = fopen(rxg_fname,"r");
	  if (rxg_fd) {
	    printf("Loading RX Gain parameters from %s\n",rxg_fname);
	    l=0;
	    while (fgets(line, sizeof(line), rxg_fd)) {
	      if ((strlen(line)==0) || (*line == '#')) continue; //ignore empty or comment lines
	      else {
		if (l==0) sscanf(line,"%d %d %d %d",&rxg_max[0],&rxg_max[1],&rxg_max[2],&rxg_max[3]);
		if (l==1) sscanf(line,"%d %d %d %d",&rxg_med[0],&rxg_med[1],&rxg_med[2],&rxg_med[3]);
		if (l==2) sscanf(line,"%d %d %d %d",&rxg_byp[0],&rxg_byp[1],&rxg_byp[2],&rxg_byp[3]);
		l++;
	      }
	    }
	  }
	  else 
	    printf("%s not found, running with defaults\n",rxg_fname);

	  sprintf(txg_fname,"%stxg.lime",optarg);
	  txg_fd = fopen(txg_fname,"r");
	  if (txg_fd) {
	    printf("Loading TX Gain parameters from %s\n",txg_fname);
	    l=0;
	    while (fgets(line, sizeof(line), txg_fd)) {
	      if ((strlen(line)==0) || (*line == '#')) {
		continue; //ignore empty or comment lines
	      }
	      else {
		if (l==0) sscanf(line,"%d %d %d %d",&txgain[0],&txgain[1],&txgain[2],&txgain[3]);
		if (l==1) sscanf(line,"%d",&tx_max_power);
		l++;
	      }
	    }
	  }
	  else 
	    printf("%s not found, running with defaults\n",txg_fname);

	  sprintf(rflo_fname,"%srflo.lime",optarg);
	  rflo_fd = fopen(rflo_fname,"r");
	  if (rflo_fd) {
	    printf("Loading RF LO parameters from %s\n",rflo_fname);
	    fscanf(rflo_fd,"%d %d %d %d",&rf_local[0],&rf_local[1],&rf_local[2],&rf_local[3]);
	  }
	  else 
	    printf("%s not found, running with defaults\n",rflo_fname);

	  sprintf(rfdc_fname,"%srfdc.lime",optarg);
	  rfdc_fd = fopen(rfdc_fname,"r");
	  if (rfdc_fd) {
	    printf("Loading RF DC parameters from %s\n",rfdc_fname);
	    fscanf(rfdc_fd,"%d %d %d %d",&rf_rxdc[0],&rf_rxdc[1],&rf_rxdc[2],&rf_rxdc[3]);
	  }
	  else 
	    printf("%s not found, running with defaults\n",rfdc_fname);

	  break;
	  /*
	case 256:
	  mode = rx_calib_ue;
	  rx_input_level_dBm = atoi(optarg);
	  printf("Running with UE calibration on (LNA max), input level %d dBm\n",rx_input_level_dBm);
	  break;
	case 257:
	  mode = rx_calib_ue_med;
	  rx_input_level_dBm = atoi(optarg);
	  printf("Running with UE calibration on (LNA med), input level %d dBm\n",rx_input_level_dBm);
	  break;
	case 258:
	  mode = rx_calib_ue_byp;
	  rx_input_level_dBm = atoi(optarg);
	  printf("Running with UE calibration on (LNA byp), input level %d dBm\n",rx_input_level_dBm);
	  break;
	case 259:
	  mode = debug_prach;
	  break;
	case 260:
	  mode = no_L2_connect;
	  break;
	  */
        default:
          break;
        }
    }

  if (UE_flag==1)
    printf("configuring for UE\n");
  else
    printf("configuring for eNB\n");

  //randominit (0);
  //set_taus_seed (0);

  // initialize the log (see log.h for details)
  logInit();

#if defined(ENABLE_ITTI)
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);

# if defined(ENABLE_USE_MME)
  if (itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
    LOG_E(EMU, "Create task failed");
    LOG_D(EMU, "Initializing SCTP task interface: FAILED\n");
    return -1;
  }
  if (itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
    LOG_E(EMU, "Create task failed");
    LOG_D(EMU, "Initializing S1AP task interface: FAILED\n");
    return -1;
  }
# endif

  if (itti_create_task(TASK_L2L1, l2l1_task, NULL) < 0) {
      LOG_E(EMU, "Create task failed");
      LOG_D(EMU, "Initializing L2L1 task interface: FAILED\n");
      return -1;
  }

  // Handle signals until all tasks are terminated
//   itti_wait_tasks_end();
#endif

  if (ouput_vcd) {
    if (UE_flag==1)
      vcd_signal_dumper_init("/tmp/openair_dump_UE.vcd");
    else
      vcd_signal_dumper_init("/tmp/openair_dump_eNB.vcd");
  }

#ifdef NAS_NETLINK
  netlink_init();
#endif

  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);

#ifndef RTAI
  check_clock();
#endif

    g_log->log_component[HW].level = LOG_DEBUG;
    g_log->log_component[HW].flag  = LOG_HIGH;
#ifdef OPENAIR2
    g_log->log_component[PHY].level = LOG_INFO;
#else
    g_log->log_component[PHY].level = LOG_INFO;
#endif
    g_log->log_component[PHY].flag  = LOG_HIGH;
    g_log->log_component[MAC].level = LOG_INFO;
    g_log->log_component[MAC].flag  = LOG_HIGH;
    g_log->log_component[RLC].level = LOG_INFO;
    g_log->log_component[RLC].flag  = LOG_HIGH;
    g_log->log_component[PDCP].level = LOG_INFO;
    g_log->log_component[PDCP].flag  = LOG_HIGH;
    g_log->log_component[OTG].level = LOG_INFO;
    g_log->log_component[OTG].flag  = LOG_HIGH;
    g_log->log_component[RRC].level = LOG_INFO;
    g_log->log_component[RRC].flag  = LOG_HIGH;


  // Initialize card
  ret = openair0_open();
  if ( ret != 0 ) {
          if (ret == -1)
              printf("Error opening /dev/openair0");
          if (ret == -2)
              printf("Error mapping bigshm");
          if (ret == -3)
              printf("Error mapping RX or TX buffer");
          return(ret);
     }

  printf ("Detected %d number of cards, %d number of antennas.\n", openair0_num_detected_cards, openair0_num_antennas[card]);
  
  p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;
  p_exmimo_id     = openair0_exmimo_pci[card].exmimo_id_ptr;
  
  printf("Card %d: ExpressMIMO %d, HW Rev %d, SW Rev 0x%d\n", card, p_exmimo_id->board_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev);

  if (p_exmimo_id->board_swrev>=BOARD_SWREV_CNTL2)
    p_exmimo_config->framing.eNB_flag   = 0; 
  else 
    p_exmimo_config->framing.eNB_flag   = !UE_flag;

  p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_LSB;
  for (ant=0; ant<4; ant++) 
    p_exmimo_config->framing.resampling_factor[ant] = RESAMPLING_FACTOR;
 
  /*
  for (ant=0;ant<max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant++) 
    p_exmimo_config->rf.rf_mode[ant] = rf_mode_base;
  for (ant=0;ant<frame_parms->nb_antennas_tx;ant++)
    p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX);
  for (ant=0;ant<frame_parms->nb_antennas_rx;ant++)
    p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX);
  for (ant=max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant<4;ant++) {
    p_exmimo_config->rf.rf_mode[ant] = 0;
    carrier_freq[ant] = 0; //this turns off all other LIMEs
  }
  */

  ant_offset = 0;
  for (ant=0; ant<4; ant++) {
    if (ant==ant_offset) {
      //if (1) {
      p_exmimo_config->rf.rf_mode[ant] = rf_mode_base;
      //p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX);
      p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX);
    }
    else {
      p_exmimo_config->rf.rf_mode[ant] = 0;
      carrier_freq[ant] = 0; //this turns off all other LIMEs
    }
  }

  for (ant = 0; ant<4; ant++) { 
    p_exmimo_config->rf.do_autocal[ant] = 1;
    p_exmimo_config->rf.rf_freq_rx[ant] = carrier_freq[ant];
    p_exmimo_config->rf.rf_freq_tx[ant] = carrier_freq[ant];
    p_exmimo_config->rf.rx_gain[ant][0] = rxgain[ant];
    p_exmimo_config->rf.tx_gain[ant][0] = txgain[ant];
    
    p_exmimo_config->rf.rf_local[ant]   = rf_local[ant];
    p_exmimo_config->rf.rf_rxdc[ant]    = rf_rxdc[ant];

    if ((carrier_freq[ant] >= 850000000) && (carrier_freq[ant] <= 865000000)) {
      p_exmimo_config->rf.rf_vcocal[ant]  = rf_vcocal_850[ant];
      p_exmimo_config->rf.rffe_band_mode[ant] = DD_TDD;	    
    }
    else if ((carrier_freq[ant] >= 1900000000) && (carrier_freq[ant] <= 2000000000)) {
      p_exmimo_config->rf.rf_vcocal[ant]  = rf_vcocal[ant];
      p_exmimo_config->rf.rffe_band_mode[ant] = B19G_TDD;	    
    }
    else {
      p_exmimo_config->rf.rf_vcocal[ant]  = rf_vcocal[ant];
      p_exmimo_config->rf.rffe_band_mode[ant] = 0;	    
    }

    p_exmimo_config->rf.rffe_gain_txlow[ant] = 31;
    p_exmimo_config->rf.rffe_gain_txhigh[ant] = 31;
    p_exmimo_config->rf.rffe_gain_rxfinal[ant] = 52;
    p_exmimo_config->rf.rffe_gain_rxlow[ant] = 31;
  }


    number_of_cards = openair0_num_detected_cards;
    /*
    if (p_exmimo_id->board_exmimoversion==1) //ExpressMIMO1
      openair_daq_vars.timing_advance = 138;
    else //ExpressMIMO2
      openair_daq_vars.timing_advance = 0;
    */

  openair0_dump_config(card);

  printf("EXMIMO_CONFIG: rf_mode 0x %x %x %x %x, [0]: TXRXEn %d, TXLPFEn %d, TXLPF %d, RXLPFEn %d, RXLPF %d, RFBB %d, LNA %d, LNAGain %d, RXLPFMode %d, SWITCH %d, rf_rxdc %d, rf_local %d, rf_vcocal %d\n",  
	 p_exmimo_config->rf.rf_mode[0],
	 p_exmimo_config->rf.rf_mode[1],
	 p_exmimo_config->rf.rf_mode[2],
	 p_exmimo_config->rf.rf_mode[3],
	 (p_exmimo_config->rf.rf_mode[0]&3),  // RXen+TXen
	 (p_exmimo_config->rf.rf_mode[0]&4)>>2,         //TXLPFen
	 (p_exmimo_config->rf.rf_mode[0]&TXLPFMASK)>>3, //TXLPF
	 (p_exmimo_config->rf.rf_mode[0]&128)>>7,      //RXLPFen
	 (p_exmimo_config->rf.rf_mode[0]&RXLPFMASK)>>8, //TXLPF
	 (p_exmimo_config->rf.rf_mode[0]&RFBBMASK)>>16, // RFBB mode
	 (p_exmimo_config->rf.rf_mode[0]&LNAMASK)>>12, // RFBB mode
	 (p_exmimo_config->rf.rf_mode[0]&LNAGAINMASK)>>14, // RFBB mode
	 (p_exmimo_config->rf.rf_mode[0]&RXLPFMODEMASK)>>19, // RXLPF mode
	 (p_exmimo_config->framing.tdd_config&TXRXSWITCH_MASK)>>1, // Switch mode
	 p_exmimo_config->rf.rf_rxdc[0],
	 p_exmimo_config->rf.rf_local[0],
	 p_exmimo_config->rf.rf_vcocal[0]);
  
  for (ant=0;ant<4;ant++)
    p_exmimo_config->rf.do_autocal[ant] = 0;

#ifdef EMOS
  error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE);
  if (error_code==0)
    printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
  else if (error_code==ENODEV)
    printf("[OPENAIR][SCHED][INIT] Problem: EMOS FIFO %d is greater than or equal to RTF_NO\n",CHANSOUNDER_FIFO_MINOR);
  else if (error_code==ENOMEM)
    printf("[OPENAIR][SCHED][INIT] Problem: cannot allocate memory for EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR);
  else 
    printf("[OPENAIR][SCHED][INIT] Problem creating EMOS FIFO %d, error_code %d\n",CHANSOUNDER_FIFO_MINOR,error_code);
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

#ifdef RTAI
  // make main thread LXRT soft realtime
  task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF);

  // start realtime timer and scheduler
#ifdef TIMER_ONESHOT_MODE
  rt_set_oneshot_mode();
  start_rt_timer(0);
  printf("started RTAI timer inoneshot mode\n");
#else
  rt_set_periodic_mode();
  period = start_rt_timer(nano2count(500000));
  printf("started RTAI timer with period %llu ns\n",count2nano(period));
#endif

  printf("Init mutex\n");
  //mutex = rt_get_adr(nam2num("MUTEX"));
  mutex = rt_sem_init(nam2num("MUTEX"), 1);
  if (mutex==0)
    {
      printf("Error init mutex\n");
      exit(-1);
    }
  else
    printf("mutex=%p\n",mutex);
#endif

  DAQ_MBOX = (volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0];

  // this starts the DMA transfers
  if (UE_flag!=1)
      openair0_start_rt_acquisition(card);


#ifdef XFORMS
  if (do_forms==1) {
      fl_initialize (&argc, argv, NULL, 0, 0);
      form_stats = create_form_stats_form();
      if (UE_flag==1) {
          form_ue[UE_id] = create_lte_phy_scope_ue();
          sprintf (title, "LTE DL SCOPE UE");
          fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
      } else {
            for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
                form_enb[UE_id] = create_lte_phy_scope_enb();
                sprintf (title, "UE%d LTE UL SCOPE eNB",UE_id+1);
                fl_show_form (form_enb[UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
            }
      }
      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
      if (UE_flag==0) {
          for (UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
              if (otg_enabled) {
                  fl_set_button(form_enb[UE_id]->button_0,1);
                  fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON");
              }
              else {
                  fl_set_button(form_enb[UE_id]->button_0,0);
                  fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic OFF");
              }
          }
      }
      else {
          if (openair_daq_vars.use_ia_receiver) {
              fl_set_button(form_ue[UE_id]->button_0,1);
              fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
          }
          else {
              fl_set_button(form_ue[UE_id]->button_0,0);
              fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
          }
      }

      ret = pthread_create(&thread2, NULL, scope_thread, NULL);
      printf("Scope thread created, ret=%d\n",ret);
    }
#endif

#ifdef EMOS
  ret = pthread_create(&thread3, NULL, emos_thread, NULL);
  printf("EMOS thread created, ret=%d\n",ret);
#endif

  rt_sleep_ns(10*FRAME_PERIOD);

#ifndef RTAI
  pthread_attr_init (&attr_dlsch_threads);
  pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
  //attr_dlsch_threads.priority = 1;
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
#endif

  // start the main thread
  if (UE_flag == 1) {
    /*
#ifdef RTAI
    thread1 = rt_thread_create(UE_thread, NULL, 100000000);
#else
    error_code = pthread_create(&thread1, &attr_dlsch_threads, UE_thread, NULL);
    if (error_code!= 0) {
      LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
      return(error_code);
    }
    else {
      LOG_D(HW,"[lte-softmodem.c] Allocate UE_thread successful\n");
    }
#endif
#ifdef DLSCH_THREAD
    init_rx_pdsch_thread();
    rt_sleep_ns(FRAME_PERIOD/10);
    init_dlsch_threads();
#endif
    printf("UE threads created\n");
    */
  }
  else {
#ifdef RTAI
    thread0 = rt_thread_create(eNB_thread, NULL, 100000000);
#else
    error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL);
    if (error_code!= 0) {
      LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code);
      return(error_code);
    }
    else {
      LOG_D(HW,"[lte-softmodem.c] Allocate eNB_thread successful\n");
    }
#endif
#ifdef ULSCH_THREAD
    init_ulsch_threads();
#endif
    printf("eNB threads created\n");
  }


  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
  while (oai_exit==0)
    rt_sleep_ns(FRAME_PERIOD);

  // stop threads
#ifdef XFORMS
  printf("waiting for XFORMS thread\n");
  if (do_forms==1)
    {
      pthread_join(thread2,&status);
        fl_hide_form(form_stats->stats_form);
        fl_free_form(form_stats->stats_form);
        if (UE_flag==1) {
            fl_hide_form(form_ue[UE_id]->lte_phy_scope_ue);
            fl_free_form(form_ue[UE_id]->lte_phy_scope_ue);
        } else {
            for(UE_id=0;UE_id<scope_enb_num_ue;UE_id++) {
                fl_hide_form(form_enb[UE_id]->lte_phy_scope_enb);
                fl_free_form(form_enb[UE_id]->lte_phy_scope_enb);
            }
        }
    }
#endif

  printf("stopping MODEM threads\n");
  // cleanup
  if (UE_flag == 1) {
    /*
#ifdef RTAI
    rt_thread_join(thread1); 
#else
    pthread_join(thread1,&status); 
#endif
#ifdef DLSCH_THREAD
    cleanup_dlsch_threads();
    cleanup_rx_pdsch_thread();
#endif
    */
  }
  else {
#ifdef RTAI
    rt_thread_join(thread0); 
#else
    pthread_join(thread0,&status); 
#endif
#ifdef ULSCH_THREAD
    cleanup_ulsch_threads();
#endif
  }

#ifdef OPENAIR2
  //cleanup_pdcp_thread();
#endif

#ifdef RTAI
  stop_rt_timer();
#endif

  printf("stopping card\n");
  openair0_stop(card);
  printf("closing openair0_lib\n");
  openair0_close();

#ifdef EMOS
  printf("waiting for EMOS thread\n");
  pthread_cancel(thread3);
  pthread_join(thread3,&status);
#endif

#ifdef EMOS
  error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR);
  printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code);
#endif

  if (ouput_vcd)
    vcd_signal_dumper_close();

  logClean();

  return 0;
}
示例#2
0
/*static*/ int
alsa_init(cubeb ** context, char const * context_name)
{
  cubeb * ctx;
  int r;
  int i;
  int fd[2];
  pthread_attr_t attr;
  snd_pcm_t * dummy;

  assert(context);
  *context = NULL;

  pthread_mutex_lock(&cubeb_alsa_mutex);
  if (!cubeb_alsa_error_handler_set) {
    snd_lib_error_set_handler(silent_error_handler);
    cubeb_alsa_error_handler_set = 1;
  }
  pthread_mutex_unlock(&cubeb_alsa_mutex);

  ctx = calloc(1, sizeof(*ctx));
  assert(ctx);

  ctx->ops = &alsa_ops;

  r = pthread_mutex_init(&ctx->mutex, NULL);
  assert(r == 0);

  r = pipe(fd);
  assert(r == 0);

  for (i = 0; i < 2; ++i) {
    fcntl(fd[i], F_SETFD, fcntl(fd[i], F_GETFD) | FD_CLOEXEC);
    fcntl(fd[i], F_SETFL, fcntl(fd[i], F_GETFL) | O_NONBLOCK);
  }

  ctx->control_fd_read = fd[0];
  ctx->control_fd_write = fd[1];

  /* Force an early rebuild when alsa_run is first called to ensure fds and
     nfds have been initialized. */
  ctx->rebuild = 1;

  r = pthread_attr_init(&attr);
  assert(r == 0);

  r = pthread_attr_setstacksize(&attr, 256 * 1024);
  assert(r == 0);

  r = pthread_create(&ctx->thread, &attr, alsa_run_thread, ctx);
  assert(r == 0);

  r = pthread_attr_destroy(&attr);
  assert(r == 0);

  /* Open a dummy PCM to force the configuration space to be evaluated so that
     init_local_config_with_workaround can find and modify the default node. */
  r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, NULL);
  if (r >= 0) {
    alsa_locked_pcm_close(dummy);
  }
  ctx->is_pa = 0;
  pthread_mutex_lock(&cubeb_alsa_mutex);
  ctx->local_config = init_local_config_with_workaround(CUBEB_ALSA_PCM_NAME);
  pthread_mutex_unlock(&cubeb_alsa_mutex);
  if (ctx->local_config) {
    ctx->is_pa = 1;
    r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, ctx->local_config);
    /* If we got a local_config, we found a PA PCM.  If opening a PCM with that
       config fails with EINVAL, the PA PCM is too old for this workaround. */
    if (r == -EINVAL) {
      pthread_mutex_lock(&cubeb_alsa_mutex);
      snd_config_delete(ctx->local_config);
      pthread_mutex_unlock(&cubeb_alsa_mutex);
      ctx->local_config = NULL;
    } else if (r >= 0) {
      alsa_locked_pcm_close(dummy);
    }
  }

  *context = ctx;

  return CUBEB_OK;
}
示例#3
0
/**
 *  Starts the thread. This method will signal to start the thread and
 *  return immediately. Note that the thread might not yet run when this
 *  method returns! The abstract method Main() is the entry point for the
 *  new thread. You have to implement the Main() method in your subclass.
 *
 *  @see StartThread()
 */
int Thread::SignalStartThread() {
#if defined(WIN32)
    LPVOID lpParameter;
    hThread = CreateThread(
               NULL, // no security attributes
               MIN_STACK_SIZE,
               __win32thread_launcher,
               this,
               0,
               &lpThreadId);
    if(hThread == NULL) {
        std::cerr << "Thread creation failed: Error" << GetLastError() << std::endl << std::flush;
        #if defined(WIN32_SIGNALSTARTTHREAD_WORKAROUND)
        win32isRunning = false;
        #else
        RunningCondition.Set(false);
        #endif
        return -1;
    }
    return 0;
#else
    // prepare the thread properties
    int res = pthread_attr_setinheritsched(&__thread_attr, PTHREAD_EXPLICIT_SCHED);
    if (res) {
        std::cerr << "Thread creation failed: Could not inherit thread properties."
                  << std::endl << std::flush;
        RunningCondition.Set(false);
        return res;
    }
    res = pthread_attr_setdetachstate(&__thread_attr, PTHREAD_CREATE_JOINABLE);
    if (res) {
        std::cerr << "Thread creation failed: Could not request a joinable thread."
                  << std::endl << std::flush;
        RunningCondition.Set(false);
        return res;
    }
    res = pthread_attr_setscope(&__thread_attr, PTHREAD_SCOPE_SYSTEM);
    if (res) {
        std::cerr << "Thread creation failed: Could not request system scope for thread scheduling."
                  << std::endl << std::flush;
        RunningCondition.Set(false);
        return res;
    }
    res = pthread_attr_setstacksize(&__thread_attr, MIN_STACK_SIZE);
    if (res) {
        std::cerr << "Thread creation failed: Could not set minimum stack size."
                  << std::endl << std::flush;
        RunningCondition.Set(false);
        return res;
    }

    // Create and run the thread
    res = pthread_create(&this->__thread_id, &__thread_attr, __pthread_launcher, this);
    switch (res) {
        case 0: // Success
            break;
        case EAGAIN:
            std::cerr << "Thread creation failed: System doesn't allow to create another thread."
                      << std::endl << std::flush;
            RunningCondition.Set(false);
            break;
        case EPERM:
            std::cerr << "Thread creation failed: You're lacking permisssions to set required scheduling policy and parameters."
                      << std::endl << std::flush;
            RunningCondition.Set(false);
            break;
        default:
            std::cerr << "Thread creation failed: Unknown cause."
                      << std::endl << std::flush;
            RunningCondition.Set(false);
            break;
    }
    return res;
#endif
}
示例#4
0
文件: data.c 项目: joolzg/tsdecrypt
void data_init(struct ts *ts) {
	memset(ts, 0, sizeof(struct ts));
	// Stream
	ts->pat	     = ts_pat_alloc();
	ts->curpat   = ts_pat_alloc();
	ts->genpat   = ts_pat_alloc();

	ts->cat      = ts_cat_alloc();
	ts->curcat   = ts_cat_alloc();

	ts->pmt      = ts_pmt_alloc();
	ts->curpmt   = ts_pmt_alloc();

	ts->sdt      = ts_sdt_alloc();
	ts->cursdt   = ts_sdt_alloc();

	ts->emm      = ts_privsec_alloc();
	ts->last_emm = ts_privsec_alloc();
	ts->tmp_emm  = ts_privsec_alloc();

	ts->ecm      = ts_privsec_alloc();
	ts->last_ecm = ts_privsec_alloc();
	ts->tmp_ecm  = ts_privsec_alloc();

	pidmap_clear(&ts->pidmap);
	pidmap_clear(&ts->cc);
	pidmap_clear(&ts->pid_seen);

	// Key
	memset(&ts->key, 0, sizeof(ts->key));
	ts->key.csakey = csa_key_alloc();
	gettimeofday(&ts->key.ts_keyset, NULL);

	// CAMD
	memset(&ts->camd, 0, sizeof(ts->camd));
	ts->camd.server_fd    = -1;
	ts->camd.server_port  = 2233;
	ts->camd.key          = &ts->key;
	ts->camd.user         = "******";
	ts->camd.pass         = "******";
	strcpy(ts->camd.newcamd.hex_des_key, "0102030405060708091011121314");

	camd_proto_cs378x(&ts->camd.ops);

	// Config
	ts->syslog_port = 514;

	ts->ts_discont  = 1;
	ts->ecm_cw_log  = 1;

	ts->debug_level = 0;
	ts->req_CA_sys  = CA_CONAX;
	ts->emm_send    = 0;
	ts->pid_filter  = 1;

	ts->emm_report_interval = 60;
	ts->emm_last_report     = time(NULL);

	ts->ecm_report_interval = 60;
	ts->ecm_last_report     = time(NULL);

	ts->cw_warn_sec = 60;
	ts->cw_last_warn= time(NULL);
	ts->cw_last_warn= ts->cw_last_warn + ts->cw_warn_sec;
	ts->key.ts      = time(NULL);

	ts->input.fd    = 0; // STDIN
	ts->input.type  = FILE_IO;

	ts->output.fd   = 1; // STDOUT
	ts->output.type = FILE_IO;
	ts->output.ttl  = 1;
	ts->output.tos  = -1;

	ts->decode_buf  = cbuf_init((7 * csa_get_batch_size() * 188) * 16, "decode"); // ~658Kb
	ts->write_buf   = cbuf_init((7 * csa_get_batch_size() * 188) *  8, "write");  // ~324Kb

	ts->input_buffer= list_new("input");

	pthread_attr_init(&ts->thread_attr);
	size_t stack_size;
	pthread_attr_getstacksize(&ts->thread_attr, &stack_size);
	if (stack_size > THREAD_STACK_SIZE)
		pthread_attr_setstacksize(&ts->thread_attr, THREAD_STACK_SIZE);
}
示例#5
0
cs_error_t sam_hc_callback_register (sam_hc_callback_t cb)
{
	cs_error_t error = CS_OK;
	pthread_attr_t thread_attr;
	int pipe_error;
	int pipe_fd[2];

	if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED) {
		return (CS_ERR_BAD_HANDLE);
	}

	if (sam_internal_data.time_interval == 0) {
		return (CS_ERR_INVALID_PARAM);
	}

	if (sam_internal_data.cb_registered) {
		sam_internal_data.hc_callback = cb;

		return (CS_OK);
	}

	/*
	 * We know, this is first registration
	 */

	if (cb == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	pipe_error = pipe (pipe_fd);

	if (pipe_error != 0) {
		/*
		 *  Pipe creation error
		 */
		error = CS_ERR_LIBRARY;
		goto error_exit;
	}

	sam_internal_data.cb_rpipe_fd = pipe_fd[0];
	sam_internal_data.cb_wpipe_fd = pipe_fd[1];

	/*
	 * Create thread attributes
	 */
	error = pthread_attr_init (&thread_attr);
	if (error != 0) {
		error = CS_ERR_LIBRARY;
		goto error_close_fd_exit;
	}


	pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setstacksize (&thread_attr, 32768);

	/*
	 * Create thread
	 */
	error = pthread_create (&sam_internal_data.cb_thread, &thread_attr, hc_callback_thread, NULL);

	if (error != 0) {
		error = CS_ERR_LIBRARY;
		goto error_attr_destroy_exit;
	}

	/*
	 * Cleanup
	 */
	pthread_attr_destroy(&thread_attr);

	sam_internal_data.cb_registered = 1;
	sam_internal_data.hc_callback = cb;

	return (CS_OK);

error_attr_destroy_exit:
	pthread_attr_destroy(&thread_attr);
error_close_fd_exit:
	sam_internal_data.cb_rpipe_fd = sam_internal_data.cb_wpipe_fd = 0;
	close (pipe_fd[0]);
	close (pipe_fd[1]);
error_exit:
	return (error);
}
示例#6
0
px4_task_t px4_task_spawn_cmd(const char *name, int scheduler, int priority, int stack_size, px4_main_t entry,
			      char *const argv[])
{

	int i;
	int argc = 0;
	unsigned int len = 0;
	struct sched_param param = {};
	char *p = (char *)argv;

	// Calculate argc
	while (p != (char *)nullptr) {
		p = argv[argc];

		if (p == (char *)nullptr) {
			break;
		}

		++argc;
		len += strlen(p) + 1;
	}

	unsigned long structsize = sizeof(pthdata_t) + (argc + 1) * sizeof(char *);

	// not safe to pass stack data to the thread creation
	pthdata_t *taskdata = (pthdata_t *)malloc(structsize + len);

	if (taskdata == nullptr) {
		return -ENOMEM;
	}

	memset(taskdata, 0, structsize + len);
	unsigned long offset = ((unsigned long)taskdata) + structsize;

	strncpy(taskdata->name, name, 16);
	taskdata->name[15] = 0;
	taskdata->entry = entry;
	taskdata->argc = argc;

	for (i = 0; i < argc; i++) {
		PX4_DEBUG("arg %d %s\n", i, argv[i]);
		taskdata->argv[i] = (char *)offset;
		strcpy((char *)offset, argv[i]);
		offset += strlen(argv[i]) + 1;
	}

	// Must add NULL at end of argv
	taskdata->argv[argc] = (char *)nullptr;

	PX4_DEBUG("starting task %s", name);

	pthread_attr_t attr;
	int rv = pthread_attr_init(&attr);

	if (rv != 0) {
		PX4_ERR("px4_task_spawn_cmd: failed to init thread attrs");
		free(taskdata);
		return (rv < 0) ? rv : -rv;
	}

#ifndef __PX4_DARWIN

	if (stack_size < PTHREAD_STACK_MIN) {
		stack_size = PTHREAD_STACK_MIN;
	}

	rv = pthread_attr_setstacksize(&attr, PX4_STACK_ADJUSTED(stack_size));

	if (rv != 0) {
		PX4_ERR("pthread_attr_setstacksize to %d returned error (%d)", stack_size, rv);
		pthread_attr_destroy(&attr);
		free(taskdata);
		return (rv < 0) ? rv : -rv;
	}

#endif

	rv = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

	if (rv != 0) {
		PX4_ERR("px4_task_spawn_cmd: failed to set inherit sched");
		pthread_attr_destroy(&attr);
		free(taskdata);
		return (rv < 0) ? rv : -rv;
	}

	rv = pthread_attr_setschedpolicy(&attr, scheduler);

	if (rv != 0) {
		PX4_ERR("px4_task_spawn_cmd: failed to set sched policy");
		pthread_attr_destroy(&attr);
		free(taskdata);
		return (rv < 0) ? rv : -rv;
	}

#ifdef __PX4_CYGWIN
	/* Priorities on Windows are defined a lot differently */
	priority = SCHED_PRIORITY_DEFAULT;
#endif

	param.sched_priority = priority;

	rv = pthread_attr_setschedparam(&attr, &param);

	if (rv != 0) {
		PX4_ERR("px4_task_spawn_cmd: failed to set sched param");
		pthread_attr_destroy(&attr);
		free(taskdata);
		return (rv < 0) ? rv : -rv;
	}

	pthread_mutex_lock(&task_mutex);

	px4_task_t taskid = 0;

	for (i = 0; i < PX4_MAX_TASKS; ++i) {
		if (!taskmap[i].isused) {
			taskmap[i].name = name;
			taskmap[i].isused = true;
			taskid = i;
			break;
		}
	}

	if (i >= PX4_MAX_TASKS) {
		pthread_attr_destroy(&attr);
		pthread_mutex_unlock(&task_mutex);
		free(taskdata);
		return -ENOSPC;
	}

	rv = pthread_create(&taskmap[taskid].pid, &attr, &entry_adapter, (void *) taskdata);

	if (rv != 0) {

		if (rv == EPERM) {
			//printf("WARNING: NOT RUNING AS ROOT, UNABLE TO RUN REALTIME THREADS\n");
			rv = pthread_create(&taskmap[taskid].pid, nullptr, &entry_adapter, (void *) taskdata);

			if (rv != 0) {
				PX4_ERR("px4_task_spawn_cmd: failed to create thread %d %d\n", rv, errno);
				taskmap[taskid].isused = false;
				pthread_attr_destroy(&attr);
				pthread_mutex_unlock(&task_mutex);
				free(taskdata);
				return (rv < 0) ? rv : -rv;
			}

		} else {
			pthread_attr_destroy(&attr);
			pthread_mutex_unlock(&task_mutex);
			free(taskdata);
			return (rv < 0) ? rv : -rv;
		}
	}

	pthread_attr_destroy(&attr);
	pthread_mutex_unlock(&task_mutex);

	return taskid;
}
示例#7
0
			void startStack(uint64_t const rstacksize = 64*1024)
			{
				if ( ! thread.get() )
				{
					thread_ptr_type tthread(new pthread_t);
					thread = UNIQUE_PTR_MOVE(tthread);

					#if 0
					std::cerr << "Creating thread without affinity." << std::endl;
					std::cerr << ::libmaus2::util::StackTrace::getStackTrace() << std::endl;
					#endif

					pthread_attr_t attr;
					if ( pthread_attr_init(&attr) )
					{
						::libmaus2::exception::LibMausException se;
						se.getStream() << "pthread_attr_init failed:" << strerror(errno);
						se.finish();
						throw se;
					}

					#if defined(PTHREAD_STACK_MIN)
					uint64_t const stacksize = std::max(rstacksize,static_cast<uint64_t>(PTHREAD_STACK_MIN));
					#else
					uint64_t const stacksize = std::max(rstacksize,static_cast<uint64_t>(64*1024));
					#endif

					if ( pthread_attr_setstacksize(&attr,stacksize) != 0 )
					{
						pthread_attr_destroy(&attr);
						::libmaus2::exception::LibMausException se;
						se.getStream() << "pthread_attr_setstacksize() failed in PosixThread::startStack(): " << strerror(errno) << std::endl;
						se.finish();
						throw se;
					}


					if ( pthread_create(thread.get(),&attr,dispatch,this) )
					{
						pthread_attr_destroy(&attr);
						::libmaus2::exception::LibMausException se;
						se.getStream() << "pthread_create() failed in PosixThread::start()";
						se.finish();
						throw se;
					}

					if ( pthread_attr_destroy(&attr) )
					{
						::libmaus2::exception::LibMausException se;
						se.getStream() << "pthread_attr_destroy failed:" << strerror(errno);
						se.finish();
						throw se;

					}
				}
				else
				{
					::libmaus2::exception::LibMausException se;
					se.getStream() << "PosixThread::start() called but object is already in use.";
					se.finish();
					throw se;
				}

			}
示例#8
0
//rtems_task Init(rtems_task_argument Argument)
void *POSIX_Init(void *argument)
{
    pthread_attr_t	threadAttr;
    pthread_t     	theThread;
    struct sched_param	sched_param;
    size_t		stack_size;
    int           	result;
    char		data[1000];
    

    memset(data, 1, sizeof(data));

    /* Set the TOD clock, so that gettimeofday() will work */
    rtems_time_of_day fakeTime = { 2006, 3, 15, 17, 30, 0, 0 };

    if (RTEMS_SUCCESSFUL != rtems_clock_set(&fakeTime))
    {
	assert(0);
    }	

    /* Bring up the network stack so we can run the socket tests. */
    initialize_network();

    /* Start a POSIX thread for pjlib_test_main(), since that's what it
     * thinks it is running in. 
     */

    /* Initialize attribute */
    TEST( pthread_attr_init(&threadAttr) );

    /* Looks like the rest of the attributes must be fully initialized too,
     * or otherwise pthread_create will return EINVAL.
     */

    /* Specify explicit scheduling request */
    TEST( pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED));

    /* Timeslicing is needed by thread test, and this is accomplished by
     * SCHED_RR.
     */
    TEST( pthread_attr_setschedpolicy(&threadAttr, SCHED_RR));

    /* Set priority */
    TEST( pthread_attr_getschedparam(&threadAttr, &sched_param));
    sched_param.sched_priority = NETWORK_STACK_PRIORITY - 10;
    TEST( pthread_attr_setschedparam(&threadAttr, &sched_param));

    /* Must have sufficient stack size (large size is needed by
     * logger, because default settings for logger is to use message buffer
     * from the stack).
     */
    TEST( pthread_attr_getstacksize(&threadAttr, &stack_size));
    if (stack_size < 8192)
	TEST( pthread_attr_setstacksize(&threadAttr, 8192));


    /* Create the thread for application */
    result = pthread_create(&theThread, &threadAttr, &pjlib_test_main, NULL);
    if (result != 0) {
	my_perror(PJ_STATUS_FROM_OS(result), 
		  "Error creating pjlib_test_main thread");
	assert(!"Error creating main thread");
    } 

    return NULL;
}
示例#9
0
Thread::Thread(int pri, size_t stack):
_cancel(cancelDefault), _start(NULL), priv(new ThreadImpl(threadTypeNormal))
{
#ifdef WIN32
	if(!_main)
	{
		_self.setKey(NULL);
		_main = this;
		setName("main()");
	}
	else
#ifdef	WIN32
		_name[0] = 0;
#else
		snprintf(_name, sizeof(_name), "%d", getId());
#endif

	_parent = Thread::get();
	if(_parent)
		priv->_throw = _parent->priv->_throw;
	else
		_parent = this;
	
	priv->_cancellation = CreateEvent(NULL, TRUE, FALSE, NULL);
	if(!priv->_cancellation)
		THROW(this);

	if(stack <= _autostack)
		priv->_stack = 0;
	else
		priv->_stack = stack;

	if(pri > 2)
		pri = 2;
	if(pri < -2)
		pri = -2;

	if(Process::isRealtime() && pri < 0)
		pri = 0;

	switch(pri)
	{
	case 1:
		priv->_priority = THREAD_PRIORITY_ABOVE_NORMAL;
		break;
	case -1:
		priv->_priority = THREAD_PRIORITY_BELOW_NORMAL;
		break;
	case 2:
		priv->_priority = THREAD_PRIORITY_HIGHEST;
		break;
	case -2:
		priv->_priority = THREAD_PRIORITY_LOWEST;
		break;
	default:
		priv->_priority = THREAD_PRIORITY_NORMAL;
	}

#else
	int	salign;

	pthread_attr_init(&priv->_attr);
	pthread_attr_setdetachstate(&priv->_attr, PTHREAD_CREATE_JOINABLE);

#ifdef	PTHREAD_STACK_MIN
	if(stack && stack <=  _autostack)
		pthread_attr_setstacksize(&priv->_attr, _autostack);
	else if(stack > _autostack)
	{
		if(stack < PTHREAD_STACK_MIN)
			stack = PTHREAD_STACK_MIN;
		else	// align to nearest min boundry
		{	
			salign = stack / PTHREAD_STACK_MIN;
			if(stack % PTHREAD_STACK_MIN)
				++salign;
			stack = salign * PTHREAD_STACK_MIN;
		}
		if(stack && pthread_attr_setstacksize(&priv->_attr, stack))
		{
#ifdef	CCXX_EXCEPTIONS
			switch(Thread::getException())
			{
			case throwObject:
				throw(this);
				return;
#ifdef	COMMON_STD_EXCEPTION
			case throwException:
				throw(ThrException("no stack space"));
				return;
#endif
			default:
				return;
			}
#else
			return;
#endif
		}
	}
#endif

#ifndef	__FreeBSD__
#ifdef	_POSIX_THREAD_PRIORITY_SCHEDULING
#ifdef HAVE_SCHED_GETSCHEDULER
#define	__HAS_PRIORITY_SCHEDULING__	
	if(pri < 0 && Process::isRealtime())
		pri = 0;

	if(pri)
	{
		struct sched_param sched;
		int policy;

		policy = sched_getscheduler(0);
		if(policy < 0)
		{
#ifdef	CCXX_EXCEPTIONS
			switch(Thread::getException())
			{
			case throwObject:
				throw(this);
				return;
#ifdef	COMMON_STD_EXCEPTION
			case throwException:
				throw(ThrException("invalid scheduler"));
				return;
#endif
			default:
				return;
			}
#else
			return;
#endif
		}

		sched_getparam(0, &sched);

		pri = sched.sched_priority - pri;
		if(pri 	> sched_get_priority_max(policy))
			pri = sched_get_priority_max(policy);

		if(pri < sched_get_priority_min(policy))
			pri = sched_get_priority_min(policy);

		sched.sched_priority = pri;
		pthread_attr_setschedpolicy(&priv->_attr, policy);
		pthread_attr_setschedparam(&priv->_attr, &sched);
	}	
#endif // ifdef HAVE_SCHED_GETSCHEDULER
#endif // ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
#endif // ifndef __FreeBSD__

#ifdef	__HAS_PRIORITY_SCHEDULING__
	if(!pri)
	        pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED);             
#else
        pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED);             
#endif

	_parent = getThread();
	priv->_throw = _parent->priv->_throw;

	_cancel = cancelInitial;

#endif // WIN32
}
示例#10
0
// create a new thread and attach to an activity
void SysThread::createThread()
{
    pthread_attr_t  newThreadAttr;
    int schedpolicy, maxpri, minpri;
    struct sched_param schedparam;

    // Create an attr block for Thread.
    pthread_attr_init(&newThreadAttr);


#if defined(LINUX) ||  defined(OPSYS_SUN) || defined(AIX)
    /* scheduling on two threads controlled by the result method of the */
    /* message object do not work properly without an enhanced priority */
    pthread_getschedparam(pthread_self(), &schedpolicy, &schedparam);

#if defined(AIX)
  // Starting with AIX 5.3 the priority for a thread created by
  // a non root user can not be higher then 59. The priority
  // of a user prog should not be higher then 59 (IBM AIX development).
  schedparam.sched_priority = 59;
#else
#   ifdef _POSIX_PRIORITY_SCHEDULING
        maxpri = sched_get_priority_max(schedpolicy);
        minpri = sched_get_priority_min(schedpolicy);
        schedparam.sched_priority = (minpri + maxpri) / 2;
#   endif
#endif

#if defined(OPSYS_SUN)
    /* PTHREAD_EXPLICIT_SCHED ==> use scheduling attributes of the new object */
//    pthread_attr_setinheritsched(&newThreadAttr, PTHREAD_EXPLICIT_SCHED);

    /* Performance measurements show massive performance improvements > 50 % */
    /* using Round Robin scheduling instead of FIFO scheduling               */
    pthread_attr_setschedpolicy(&newThreadAttr, SCHED_RR);
#endif

#if defined(AIX)
    /* PTHREAD_EXPLICIT_SCHED ==> use scheduling attributes of the new object */
 //   pthread_attr_setinheritsched(&newThreadAttr, PTHREAD_EXPLICIT_SCHED);

    /* Each thread has an initial priority that is dynamically modified by   */
    /* the scheduler, according to the thread's activity; thread execution   */
    /* is time-sliced. On other systems, this scheduling policy may be       */
    /* different.                                                            */
    pthread_attr_setschedpolicy(&newThreadAttr, SCHED_OTHER);
#endif

    pthread_attr_setschedparam(&newThreadAttr, &schedparam);
#endif

    // Set the stack size.
    pthread_attr_setstacksize(&newThreadAttr, THREAD_STACK_SIZE);

    // Now create the thread
    int rc = pthread_create(&_threadID, &newThreadAttr, call_thread_function, (void *)this);

    if (rc != 0)
    {
        _threadID = 0;
        fprintf(stderr," *** ERROR: At SysThread(), createThread - RC = %d !\n", rc);
    }
    pthread_attr_destroy(&newThreadAttr);
    attached = false;           // we own this thread
    return;
}
示例#11
0
VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread,
                                 const char *name,
                                 VCOS_THREAD_ATTR_T *attrs,
                                 VCOS_THREAD_ENTRY_FN_T entry,
                                 void *arg)
{
   VCOS_STATUS_T st;
   pthread_attr_t pt_attrs;
   VCOS_THREAD_ATTR_T *local_attrs = attrs ? attrs : &default_attrs;
   int rc;

   vcos_assert(thread);
   memset(thread, 0, sizeof(VCOS_THREAD_T));

   rc = pthread_attr_init(&pt_attrs);
   if (rc < 0)
      return VCOS_ENOMEM;

   st = vcos_semaphore_create(&thread->suspend, NULL, 0);
   if (st != VCOS_SUCCESS)
   {
      pthread_attr_destroy(&pt_attrs);
      return st;
   }

   pthread_attr_setstacksize(&pt_attrs, local_attrs->ta_stacksz);
#if VCOS_CAN_SET_STACK_ADDR
   if (local_attrs->ta_stackaddr)
   {
      pthread_attr_setstackaddr(&pt_attrs, local_attrs->ta_stackaddr);
   }
#else
   vcos_demand(local_attrs->ta_stackaddr == 0);
#endif

   /* pthread_attr_setpriority(&pt_attrs, local_attrs->ta_priority); */

   vcos_assert(local_attrs->ta_stackaddr == 0); /* Not possible */

   thread->entry = entry;
   thread->arg = arg;
   thread->legacy = local_attrs->legacy;

   strncpy(thread->name, name, sizeof(thread->name));
   thread->name[sizeof(thread->name)-1] = '\0';
   memset(thread->at_exit, 0, sizeof(thread->at_exit));

   rc = pthread_create(&thread->thread, &pt_attrs, vcos_thread_entry, thread);

   pthread_attr_destroy(&pt_attrs);

   if (rc < 0)
   {
      vcos_semaphore_delete(&thread->suspend);
      return VCOS_ENOMEM;
   }
   else
   {
      return VCOS_SUCCESS;
   }
}
示例#12
0
/* Might be called back from NovaWin_StartExecService */
void StartServer(Policy *policy, GenericAgentConfig *config, ExecConfig *exec_config, const ReportContext *report_context)
{
#if !defined(__MINGW32__)
    time_t now = time(NULL);
#endif
    Promise *pp = NewPromise("exec_cfengine", "the executor agent");
    Attributes dummyattr;
    CfLock thislock;

    pthread_attr_init(&threads_attrs);
    pthread_attr_setdetachstate(&threads_attrs, PTHREAD_CREATE_DETACHED);
    pthread_attr_setstacksize(&threads_attrs, (size_t)2048*1024);

    Banner("Starting executor");
    memset(&dummyattr, 0, sizeof(dummyattr));

    dummyattr.restart_class = "nonce";
    dummyattr.transaction.ifelapsed = CF_EXEC_IFELAPSED;
    dummyattr.transaction.expireafter = CF_EXEC_EXPIREAFTER;

    if (!ONCE)
    {
        thislock = AcquireLock(pp->promiser, VUQNAME, CFSTARTTIME, dummyattr, pp, false);

        if (thislock.lock == NULL)
        {
            DeletePromise(pp);
            return;
        }

        /* Kill previous instances of cf-execd if those are still running */
        Apoptosis();

        /* FIXME: kludge. This code re-sets "last" lock to the one we have
           acquired a few lines before. If the cf-execd is terminated, this lock
           will be removed, and subsequent restart of cf-execd won't fail.

           The culprit is Apoptosis(), which creates a promise and executes it,
           taking locks during it, so CFLOCK/CFLAST/CFLOG get reset.

           Proper fix is to keep all the taken locks in the memory, and release
           all of them during process termination.
         */
        strcpy(CFLOCK, thislock.lock);
        strcpy(CFLAST, thislock.last ? thislock.last : "");
        strcpy(CFLOG, thislock.log ? thislock.log : "");
    }

#ifdef __MINGW32__

    if (!NO_FORK)
    {
        CfOut(cf_verbose, "", "Windows does not support starting processes in the background - starting in foreground");
    }

#else /* !__MINGW32__ */

    if ((!NO_FORK) && (fork() != 0))
    {
        CfOut(cf_inform, "", "cf-execd starting %.24s\n", cf_ctime(&now));
        _exit(0);
    }

    if (!NO_FORK)
    {
        ActAsDaemon(0);
    }

#endif /* !__MINGW32__ */

    WritePID("cf-execd.pid");
    signal(SIGINT, HandleSignalsForDaemon);
    signal(SIGTERM, HandleSignalsForDaemon);
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGUSR1, HandleSignalsForDaemon);
    signal(SIGUSR2, HandleSignalsForDaemon);

    umask(077);

    if (ONCE)
    {
        CfOut(cf_verbose, "", "Sleeping for splaytime %d seconds\n\n", SPLAYTIME);
        sleep(SPLAYTIME);
        LocalExec(exec_config);
        CloseLog();
    }
    else
    {
        while (!IsPendingTermination())
        {
            if (ScheduleRun(&policy, config, exec_config, report_context))
            {
                CfOut(cf_verbose, "", "Sleeping for splaytime %d seconds\n\n", SPLAYTIME);
                sleep(SPLAYTIME);

                if (!LocalExecInThread(exec_config))
                {
                    CfOut(cf_inform, "", "Unable to run agent in thread, falling back to blocking execution");
                    LocalExec(exec_config);
                }
            }
        }

        YieldCurrentLock(thislock);
    }
}
示例#13
0
sc_cor*
sc_cor_pkg_pthread::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
{
    sc_cor_pthread* cor_p = new sc_cor_pthread;
    DEBUGF << &main_cor << ": sc_cor_pkg_pthread::create("
    << cor_p << ")" << std::endl;


    // INITIALIZE OBJECT'S FIELDS FROM ARGUMENT LIST:

    cor_p->m_pkg_p = this;
    cor_p->m_cor_fn = fn;
    cor_p->m_cor_fn_arg = arg;


    // SET UP THREAD CREATION ATTRIBUTES:
    //
    // Use default values except for stack size. If stack size is non-zero
    // set it.

    pthread_attr_t attr;
    pthread_attr_init( &attr );
    if ( stack_size != 0 )
    {
        pthread_attr_setstacksize( &attr, stack_size );
    }


    // ALLOCATE THE POSIX THREAD TO USE AND FORCE SEQUENTIAL EXECUTION:
    //
    // Because pthread_create causes the created thread to be executed,
    // we need to let it run until we can block in the invoke_module_method.
    // So we:
    //   (1) Lock the creation mutex before creating the new thread.
    //   (2) Sleep on the creation condition, which will be signalled by
    //       the newly created thread just before it goes to sleep in
    //       invoke_module_method.
    // This scheme results in the newly created thread being dormant before
    // the main thread continues execution.

    pthread_mutex_lock( &create_mutex );
    DEBUGF << &main_cor << ": about to create actual thread "
    << cor_p << std::endl;
    if ( pthread_create( &cor_p->m_thread, &attr,
                         &sc_cor_pthread::invoke_module_method, (void*)cor_p ) )
    {
        std::fprintf(stderr, "ERROR - could not create thread\n");
    }

    DEBUGF << &main_cor << ": main thread waiting for signal from "
    << cor_p << std::endl;
    pthread_cond_wait( &create_condition, &create_mutex );
    DEBUGF << &main_cor << ": main thread signaled by "
    << cor_p << endl;
    pthread_attr_destroy( &attr );
    pthread_mutex_unlock( &create_mutex );
    DEBUGF << &main_cor << ": exiting sc_cor_pkg_pthread::create("
    << cor_p << ")" << std::endl;

    return cor_p;
}
示例#14
0
int main( int argc, char **argv )
{
    void *retval;
    pthread_attr_t attr;
    struct sched_param schedparam;

    CYG_TEST_INIT();

    sa.sin_family = AF_INET;
    sa.sin_len = sizeof(sa);
    inet_aton("127.0.0.1", &sa.sin_addr);
    sa.sin_port = htons(1234);
    init_all_network_interfaces();
    
    // Create test threads

    {
        pthread_attr_init( &attr );

        schedparam.sched_priority = 5;
        pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
        pthread_attr_setschedpolicy( &attr, SCHED_RR );
        pthread_attr_setschedparam( &attr, &schedparam );
        pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
        pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );

        pthread_create( &thread1,
                        &attr,
                        pthread_entry1,
                        (void *)0x12345671);
    }

    {
        pthread_attr_init( &attr );

        schedparam.sched_priority = 10;
        pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
        pthread_attr_setschedpolicy( &attr, SCHED_RR );
        pthread_attr_setschedparam( &attr, &schedparam );
        pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
        pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );

        pthread_create( &thread2,
                        &attr,
                        pthread_entry2,
                        (void *)0x12345672);
    }
    
    // Now join with thread1
    CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
    pthread_join( thread1, &retval );

    // And thread 2
    CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
    pthread_join( thread2, &retval );

    diag_printf("INFO: pselect returns: %d\n", pselect_wakeups );
    diag_printf("INFO: pselect EINTR returns: %d\n", pselect_eintr );
    diag_printf("INFO: SIGUSR1 sent: %d\n", sigusr1_sent );
    diag_printf("INFO: SIGUSR1 delivered: %d\n", sigusr1_calls );
    
    CYG_TEST_CHECK( sigusr1_sent == sigusr1_calls, "SIGUSR1 calls != delivered");
    CYG_TEST_CHECK( sigusr1_sent == pselect_eintr, "SIGUSR1 calls != pselect EINTR wakeups");
    
    CYG_TEST_PASS_FINISH("pselect");
}
示例#15
0
int init_pthread_attr(pthread_attr_t *pattr, const int stack_size)
{
    size_t old_stack_size;
    size_t new_stack_size;
    int result;

    if ((result=pthread_attr_init(pattr)) != 0)
    {
        /*logError("file: "__FILE__", line: %d, " \
            "call pthread_attr_init fail, " \
            "errno: %d, error info: %s", \
            __LINE__, result, STRERROR(result));*/
        return result;
    }

    if ((result=pthread_attr_getstacksize(pattr, &old_stack_size)) != 0)
    {
        /*logError("file: "__FILE__", line: %d, " \
            "call pthread_attr_getstacksize fail, " \
            "errno: %d, error info: %s", \
            __LINE__, result, STRERROR(result));*/
        return result;
    }

    if (stack_size > 0)
    {
        if (old_stack_size != stack_size)
        {
            new_stack_size = stack_size;
        }
        else
        {
            new_stack_size = 0;
        }
    }
    else if (old_stack_size < 1 * 1024 * 1024)
    {
        new_stack_size = 1 * 1024 * 1024;
    }
    else
    {
        new_stack_size = 0;
    }

    if (new_stack_size > 0)
    {
        if ((result=pthread_attr_setstacksize(pattr, \
                new_stack_size)) != 0)
        {
            /*logError("file: "__FILE__", line: %d, " \
                "call pthread_attr_setstacksize fail, " \
                "errno: %d, error info: %s", \
                __LINE__, result, STRERROR(result));*/
            return result;
        }
    }

    if ((result=pthread_attr_setdetachstate(pattr, \
            PTHREAD_CREATE_DETACHED)) != 0)
    {
        /*logError("file: "__FILE__", line: %d, " \
            "call pthread_attr_setdetachstate fail, " \
            "errno: %d, error info: %s", \
            __LINE__, result, STRERROR(result));*/
        return result;
    }

    return 0;
}
示例#16
0
McastResult* run_tests(int n_addr, int n_stream, char *start_addr, int startPort, int bufLen, int *jitterSize, int timeout, int verbose){
	int i,j,rc;
	int n_thread = n_addr * n_stream;
	pthread_t thr[n_thread];
	mthread_data_t thr_data[n_thread];
    pthread_attr_t thread_attr;
	pthread_attr_init(&thread_attr);
	pthread_attr_setstacksize(&thread_attr , PTHREAD_STACK_MIN );
	
	char *plural_s = "";
	if (n_stream > 1) plural_s = "s";
	char *plural_a = "";
	if (n_addr > 1) plural_a = "es";
	if (verbose == 1){
		printf("Receiving from %d Multicast Address%s (starting at %s:%d) over %d stream%s.\n", n_addr, plural_a, start_addr, startPort, n_stream, plural_s);
	}
	for (i = 0; i < n_addr; i++){
		for (j = 0; j < n_stream; j++){
			int ind = i * n_stream + j;
			sprintf(thr_data[ind].port, "%d", startPort + ind);
			sprintf(thr_data[ind].addr, "%s", increment_address(start_addr, i));
			thr_data[ind].bufLen = bufLen;
			thr_data[ind].sock = sockets[ind];
			thr_data[ind].jitterSize = *jitterSize;
			thr_data[ind].timeout = timeout;
			thr_data[ind].stat = createMcastStat(*jitterSize);
		} 
	}
	
	// loop again to ensure things start at same time.
	for (i = 0; i < n_thread; i++){
		if ((rc = pthread_create(&thr[i], &thread_attr, run_subtest, &thr_data[i])) < 0) {
			printf("pthread_create rc: %d\n", rc);
			fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
			return NULL;
		}
	} 
	
	int ntime = 0;
	for (i = 0; i < n_thread; i++){
		pthread_join(thr[i], NULL);
	}
	int nerr = 0;
	McastStat *res = createMcastStat(*jitterSize);
	for (i = 0; i < n_thread; i++){	
		McastStat *stat = thr_data[i].stat;
		if (thr_data[i].timeout == -1){
			nerr++;
		}
		else {
			ntime = stat->ttime;
			res->lost += stat->lost;
			res->rcvd += stat->rcvd;
			res->ttime += stat->ttime;
			res->bytes += stat->bytes;
			float rj = res->rollingJitter;
			for (j = 0; j < stat->used; j++){
				insertJitter(res, stat->jitters[j]);
			}
			res->rollingJitter = rj + stat->rollingJitter;		
			if (stat->used > *jitterSize){
				*jitterSize = stat->used;
			}
		}
		freeMcastStat(stat);
	}
	res->ttime += ntime * nerr;
	if (nerr >= (n_thread + 1) / 2 || computeBitrate(res) < 0.01){
		return (McastResult *)NULL;
	}	
	
	res->rollingJitter /= (n_thread - nerr);
	McastResult* r = computeMcastResult(res, n_addr, n_stream);
	freeMcastStat(res);
	return r;
}
示例#17
0
文件: 1-1.c 项目: Nan619/ltp-ddt
int main()
{
	pthread_t new_th;
	pthread_attr_t attr;
	size_t stack_size = PTHREAD_STACK_MIN;
	size_t ssize;
	void *saddr;
	int rc;

	/* Initialize attr */
	rc = pthread_attr_init(&attr);
	if (rc != 0) {
		perror(ERROR_PREFIX "pthread_attr_init");
		exit(PTS_UNRESOLVED);
	}

	/* printf("stack_size = %lu\n", stack_size); */

	rc = posix_memalign(&saddr, sysconf(_SC_PAGE_SIZE), stack_size);

	if (rc != 0) {
		printf(ERROR_PREFIX "out of memory while "
		       "allocating the stack memory: %s", strerror(rc));
		exit(PTS_UNRESOLVED);
	}

	rc = pthread_attr_setstacksize(&attr, stack_size);
	if (rc != 0) {
		printf(ERROR_PREFIX "pthread_attr_setstacksize: %s",
		       strerror(rc));
		exit(PTS_UNRESOLVED);
	}

	rc = pthread_attr_getstacksize(&attr, &ssize);
	if (rc != 0) {
		printf(ERROR_PREFIX "pthread_attr_getstacksize: %s",
		       strerror(rc));
		exit(PTS_UNRESOLVED);
	}
	/* printf("stack_size = %lu\n", ssize); */

	rc = pthread_create(&new_th, &attr, thread_func, NULL);
	if (rc != 0) {
		printf(ERROR_PREFIX "failed to create a thread: %s",
		       strerror(rc));
		exit(PTS_FAIL);
	}

	rc = pthread_join(new_th, NULL);
	if (rc != 0) {
		printf(ERROR_PREFIX "pthread_join: %s", strerror(rc));
		exit(PTS_UNRESOLVED);
	}

	rc = pthread_attr_destroy(&attr);
	if (rc != 0) {
		printf(ERROR_PREFIX "pthread_attr_destroy: %s", strerror(rc));
		exit(PTS_UNRESOLVED);
	}

	printf("Test PASSED\n");
	return PTS_PASS;
}
示例#18
0
        int Start(bool realtime)
        {
            pthread_attr_t attributes;
            struct sched_param rt_param;
            pthread_attr_init(&attributes);
            
            int priority = 60; // TODO
            int res;
            
            if (realtime) {
                fRealTime = true;
            }else {
                fRealTime = getenv("OMP_REALTIME") ? strtol(getenv("OMP_REALTIME"), NULL, 10) : true;
            }
                                   
            if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
                printf("Cannot request joinable thread creation for real-time thread res = %d err = %s\n", res, strerror(errno));
                return -1;
            }

            if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
                printf("Cannot set scheduling scope for real-time thread res = %d err = %s\n", res, strerror(errno));
                return -1;
            }

            if (realtime) {
                
                if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
                    printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
                    return -1;
                }
            
                if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) {
                    printf("Cannot set RR scheduling class for RT thread res = %d err = %s\n", res, strerror(errno));
                    return -1;
                }
                
                memset(&rt_param, 0, sizeof(rt_param));
                rt_param.sched_priority = priority;

                if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
                    printf("Cannot set scheduling priority for RT thread res = %d err = %s\n", res, strerror(errno));
                    return -1;
                }

            } else {
                
                if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_INHERIT_SCHED))) {
                    printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno));
                    return -1;
                }
            }
         
            if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) {
                printf("Cannot set thread stack size res = %d err = %s\n", res, strerror(errno));
                return -1;
            }
            
            if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
                printf("Cannot create thread res = %d err = %s\n", res, strerror(errno));
                return -1;
            }
            
            // Set affinity
            set_affinity(fThread, fNumThread + 1);

            pthread_attr_destroy(&attributes);
            return 0;
        }
示例#19
0
static int my_pthread_attr_setstacksize(pthread_attr_t *__attr, size_t stacksize)
{
	pthread_attr_t *realattr = (pthread_attr_t *) *(int *) __attr;
	return pthread_attr_setstacksize (realattr,stacksize);
}
示例#20
0
/***** The next function initializes a cell_t object
 * This includes running the threads */
void cell_init(int id, cell_t * c, pthread_mutexattr_t *pma)
{
	int ret, i;
	pthread_attr_t  pa; /* We will specify a minimal stack size */

	/* mark this group with its ID */
	c->id = id; 
	/* Initialize some other values */
	c->sigok = 0;
	c->ctrl = 0;
	c->sigcnt = 0;
	c->opcnt = 0;
	c->tcnt = 0;
	
	/* Initialize the mutex */
	ret = pthread_mutex_init(&(c->tmtx), NULL); 
	if (ret != 0)
	{  UNRESOLVED(ret, "Mutex init failed"); }
	ret = pthread_mutex_init(&(c->mtx), pma); 
	if (ret != 0)
	{  UNRESOLVED(ret, "Mutex init failed"); }
	#if VERBOSE > 1
	output("Mutex initialized in cell %i\n", id);
	#endif

	/* Initialize the semaphore */
	ret = sem_init(&(c->semsig), 0, 0); 
	if (ret != 0)
	{  UNRESOLVED(errno, "Sem init failed"); }
	#if VERBOSE > 1
	output("Semaphore initialized in cell %i\n", id);
	#endif
	
	/* Create the thread attribute with the minimal size */
	ret = pthread_attr_init(&pa);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to create pthread attribute object");  }
	ret = pthread_attr_setstacksize(&pa, sysconf(_SC_THREAD_STACK_MIN));
	if (ret != 0)
 	{  UNRESOLVED(ret, "Unable to specify minimal stack size");  }
	
	
	/* Create the signal thread */
	ret = pthread_create(&(c->threads[0]), &pa, sigthr, (void *) c);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to create the signal thread"); }
	
	/* Create 5 "lock" threads */
	for (i=1; i<=5; i++)
	{
		ret = pthread_create(&(c->threads[i]), &pa, lockthr, (void *) c);
		if (ret != 0)
		{  UNRESOLVED(ret, "Unable to create a locker thread"); }
	}

	/* Create 2 "timedlock" threads */
	for (i=6; i<=7; i++)
	{
		ret = pthread_create(&(c->threads[i]), &pa, timedlockthr, (void *) c);
		if (ret != 0)
		{  UNRESOLVED(ret, "Unable to create a (timed) locker thread"); }
	}

	/* Create 2 "trylock" threads */
	for (i=8; i<=9; i++)
	{
		ret = pthread_create(&(c->threads[i]), &pa, trylockthr, (void *) c);
		if (ret != 0)
		{  UNRESOLVED(ret, "Unable to create a (try) locker thread"); }
	}

	#if VERBOSE > 1
	output("All threads initialized in cell %i\n", id);
	#endif
	
	/* Destroy the thread attribute object */
	ret = pthread_attr_destroy(&pa);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to destroy thread attribute object");  }
	
	/* Tell the signal thread to start working */
	ret = sem_post(&(c->semsig));
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to post signal semaphore");  }
}
示例#21
0
int main(int argc, char ** argv) {
  pthread_t threads[THREAD_COUNT];
  pthread_attr_t attr;
  int result;
  int i;
  int iteration;
  int finished;

  initSignalling();
  
  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr, 128*1024);

  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  
  pthread_key_create(&pKey, NULL);

  for (iteration = 0; iteration < ITER_COUNT; iteration++) {
#if 0
     if ((iteration % 100) == 0) {
	printf("\nStarting run series %i: ", iteration);
     }

     if ((iteration % 10) == 0) {
	printf(".");
        fflush(stdout);
     }
#endif

      // Clear array
      for (i = 0; i< THREAD_COUNT; i++) {
	 finishedArray[i] = 0;
      }

      // Start threads
      for (i = 0; i< THREAD_COUNT; i++) {
	 result = pthread_create(&threads[i], &attr, threadfunc, (void*)i);
	 if (result != 0) {
	    perror("pthread_create");
	    exit(1);
	 }
    }
    
//    printf("all threads started\n");
    // suspend threads
    for (i = 0; i< THREAD_COUNT; i++) {
    	suspendOrResume(threads[i], i);
    }
    
//    printf("now all threads are suspended\n");
    
    // resume threads
    for (i = 0; i< THREAD_COUNT; i++) {
    	suspendOrResume(threads[i], i);
    }
    

      // Join threads
/*      
      printf("about to join...");
      for (i = 0; i< THREAD_COUNT; i++) {
	 result = pthread_join(threads[i], NULL);
	 if (result != 0) {
	    perror("pthread_join");
	    exit(1);
	 }
      }
      
      printf("...joined");
*/      
//      printf("Spin waiting for results\n");
      finished = 1;
      do {
   struct timespec req, rem;

   req.tv_sec = 0;
   req.tv_nsec = 5 * 1000 * 1000;
   finished = 1;

   nanosleep(&req, &rem);
         
//         sleep(1);
         for (i = 0; i< THREAD_COUNT; i++) {
            if (finishedArray[i] < 2) {
               finished = 0;
//               printf("no result at: %d, value: %d\n", i, finishedArray[i]);
               break;
            }
	 }
//         sleep(1);
      } while (!finished);

  }

  printf("PASSED\n");
  return 0;
}
示例#22
0
文件: main.c 项目: epall/soundmodem
static int parsecfg(xmlDocPtr doc, xmlNodePtr node, struct state *state, unsigned int *schedrr)
{
	xmlNodePtr audio = NULL;
	xmlNodePtr ptt = NULL;
	const char *par[MAXPAR];
	struct modemchannel *chan;
        pthread_attr_t rxattr;
	size_t stacksize;
	unsigned int samplerate = 5000, mode;

	for (; node; node = node->next) {
		if (node->type != XML_ELEMENT_NODE) 
			continue; 
		if (!node->name)
			logprintf(MLOG_FATAL, "Node has no name\n");
		if (!strcmp(node->name, "audio")) {
			audio = node;
			continue;
		}
		if (!strcmp(node->name, "ptt")) {
			ptt = node;
			continue;
		}
		if (!strcmp(node->name, "chaccess")) {
			getparam(doc, node, chaccparams, par);
			if (par[0])
				state->chacc.txdelay = strtoul(par[0], NULL, 0);
			if (par[1])
				state->chacc.slottime = strtoul(par[1], NULL, 0);
			if (par[2])
				state->chacc.ppersist = strtoul(par[2], NULL, 0);
			if (par[3])
				state->chacc.fullduplex = !!strtoul(par[3], NULL, 0);
			if (par[4])
				state->chacc.txtail = strtoul(par[4], NULL, 0);
			continue;
		}
		if (!strcmp(node->name, "channel")) {
			if (node->children)
				parsechannel(doc, node->children, state, &samplerate);
			continue;
		}
		logprintf(MLOG_ERROR, "unknown node \"%s\"\n", node->name);
	}
        /* find audio mode */
        mode = 0;
        for (chan = state->channels; chan; chan = chan->next) {
                if (chan->demod && chan->demod->demodulate)
                        mode |= IO_RDONLY;
                if (chan->mod && chan->mod->modulate)
                        mode |= IO_WRONLY;
        }
	if (!state->channels || !mode) {
		logprintf(MLOG_ERROR, "no channels configured\n");
		return -1;
	}
        /* open PTT */
	getparam(doc, ptt, pttparams, par);
	if (pttinit(&state->ptt, par))
                logprintf(MLOG_ERROR, "cannot start PTT output\n");
        /* open audio */
	getparam(doc, audio, ioparam_type, par);
	if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[1])) {
		getparam(doc, audio, ioparams_filein, par);
		state->audioio = ioopen_filein(&samplerate, IO_RDONLY, par);
		if (schedrr)
			*schedrr = 0;
	} else if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[2])) {
                getparam(doc, audio, ioparams_sim, par);
		state->audioio = ioopen_sim(&samplerate, IO_RDWR, par);
		if (schedrr)
			*schedrr = 0;
#ifdef HAVE_ALSA
	} else if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[3])) {
                getparam(doc, audio, ioparams_alsasoundcard, par);
		state->audioio = ioopen_alsasoundcard(&samplerate, mode, par);
#endif /* HAVE_ALSA */
	} else {
		getparam(doc, audio, ioparams_soundcard, par);
		state->audioio = ioopen_soundcard(&samplerate, mode, par);
	}
	if (!state->audioio)
                logprintf(MLOG_FATAL, "cannot start audio\n");
	for (chan = state->channels; chan; chan = chan->next) {
		if (chan->demod) {
			chan->demod->init(chan->demodstate, samplerate, &chan->rxbitrate);
                        if (pthread_attr_init(&rxattr))
				logerr(MLOG_FATAL, "pthread_attr_init");
			/* needed on FreeBSD, according to [email protected] */
			if (pthread_attr_getstacksize(&rxattr, &stacksize))
				logerr(MLOG_ERROR, "pthread_attr_getstacksize");
			else if (stacksize < 256*1024)
				if (pthread_attr_setstacksize(&rxattr, 256*1024))
					logerr(MLOG_ERROR, "pthread_attr_setstacksize");
#ifdef HAVE_SCHED_H
                        if (schedrr && *schedrr) {
                                struct sched_param schp;
                                memset(&schp, 0, sizeof(schp));
                                schp.sched_priority = sched_get_priority_min(SCHED_RR)+1;
                                if (pthread_attr_setschedpolicy(&rxattr, SCHED_RR))
                                        logerr(MLOG_ERROR, "pthread_attr_setschedpolicy");
                                if (pthread_attr_setschedparam(&rxattr, &schp))
                                        logerr(MLOG_ERROR, "pthread_attr_setschedparam");
                        }
#endif /* HAVE_SCHED_H */
			if (pthread_create(&chan->rxthread, &rxattr, demodthread, chan))
				logerr(MLOG_FATAL, "pthread_create");
                        pthread_attr_destroy(&rxattr);
		}
		if (chan->mod)
			chan->mod->init(chan->modstate, samplerate);
	}
	return 0;
}
示例#23
0
/* protected functions */
void
os_processModuleInit(void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    struct sigaction action;
    pthread_attr_t      thrAttr;
    int result;

     result = pipe(_ospl_signalpipe);

    pthread_attr_init(&thrAttr);
    pthread_attr_setstacksize(&thrAttr, 4*1024*1024); /* 4MB */
    pthread_create(&_ospl_signalHandlerThreadId, &thrAttr, signalHandlerThread, (void*)0);


    /* install signal handlers */
    action.sa_handler = 0;
    action.sa_sigaction = signalHandler;
    sigfillset(&action.sa_mask); /* block all signals during handling of a signal */
    action.sa_flags = SA_SIGINFO;


    _SIGCURRENTACTION_(SIGINT);

    /* If the user has set a signal handler or explicitly told the system to
     * ignore the signal, we don't set a handler ourselves. It's the
     * responsibility of the user to make sure exit() is called to
     * terminate the application to make sure all shared memory resources
     * are properly cleaned up. This is on a per signal basis.
     */
    if ((_SIGNALVECTOR_(SIGINT).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGINT).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGINT);
    }
    _SIGCURRENTACTION_(SIGQUIT);

    if ((_SIGNALVECTOR_(SIGQUIT).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGQUIT).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGQUIT);
    }
    _SIGCURRENTACTION_(SIGHUP);

    if ((_SIGNALVECTOR_(SIGHUP).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGHUP).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGHUP);
    }
    _SIGCURRENTACTION_(SIGTERM);

    if ((_SIGNALVECTOR_(SIGTERM).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGTERM).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGTERM);
    }

    if(isSignallingSafe(1)){
        _SIGCURRENTACTION_(SIGILL);

        if ((_SIGNALVECTOR_(SIGILL).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGILL).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGILL);
        }
        _SIGCURRENTACTION_(SIGABRT);

        if ((_SIGNALVECTOR_(SIGABRT).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGABRT).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGABRT);
        }
        _SIGCURRENTACTION_(SIGFPE);

        if ((_SIGNALVECTOR_(SIGFPE).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGFPE).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGFPE);
        }
        _SIGCURRENTACTION_(SIGSEGV);

        if ((_SIGNALVECTOR_(SIGSEGV).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGSEGV).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGSEGV);
        }
        _SIGCURRENTACTION_(SIGPIPE);

        if ((_SIGNALVECTOR_(SIGPIPE).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGPIPE).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGPIPE);
        }
        _SIGCURRENTACTION_(SIGALRM);

        if ((_SIGNALVECTOR_(SIGALRM).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGALRM).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGALRM);
        }
        _SIGCURRENTACTION_(SIGUSR1);

        if ((_SIGNALVECTOR_(SIGUSR1).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGUSR1).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGUSR1);
        }
        _SIGCURRENTACTION_(SIGUSR2);

        if ((_SIGNALVECTOR_(SIGUSR2).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGUSR2).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGUSR2);
        }
        /* Only in newer POSIX versions, ignoring for now
        _SIGCURRENTACTION_(SIGTSTOP);
        _SIGACTION_(SIGTSTOP);
        */
        _SIGCURRENTACTION_(SIGTTIN);

        if ((_SIGNALVECTOR_(SIGTTIN).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGTTIN).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGTTIN);
        }
        /* Only in newer POSIX versions, ignoring for now
        _SIGCURRENTACTION_(SIGTTOUT);
        _SIGACTION_(SIGTTOUT);
        */
    }
#endif
}
示例#24
0
int main(int argc, char *argv[])
{
    int s, tnum, opt, num_threads;
    struct thread_info *tinfo;
    pthread_attr_t attr;
    int stack_size;
    void *res;

    /* The "-s" option specifies a stack size for our threads */
    stack_size = -1;
    while ((opt = getopt(argc, argv, "s:")) != -1) {
        switch (opt) {
        case 's':
            stack_size = strtoul(optarg, NULL, 0);
            break;
        default:
            fprintf(stderr, "Usage: %s [-s stack-size] arg...\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    num_threads = argc - optind;

    /* Initialize thread creation attributes */
    s = pthread_attr_init(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_init");

    if (stack_size > 0) {
        s = pthread_attr_setstacksize(&attr, stack_size);
        if (s != 0)
            handle_error_en(s, "pthread_attr_setstacksize");
    }

    /* Allocate memory for pthread_create() arguments */
    tinfo = calloc(num_threads, sizeof(struct thread_info));
    if (tinfo == NULL)
        handle_error("calloc");

    /* Create one thread for each command-line argument */
    for (tnum = 0; tnum < num_threads; tnum++) {
        tinfo[tnum].thread_num = tnum + 1;
        tinfo[tnum].argv_string = argv[optind + tnum];

        /* The pthread_create() call stores the thread ID into
           corresponding element of tinfo[] */
        s = pthread_create(&tinfo[tnum].thread_id, &attr,
                           &thread_start, &tinfo[tnum]);
        if (s != 0)
            handle_error_en(s, "pthread_create");
    }

    /* Destroy the thread attributes object, since it is no
       longer needed */
    s = pthread_attr_destroy(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_destroy");

    /* Now join with each thread, and display its returned value */
    for (tnum = 0; tnum < num_threads; tnum++) {
        s = pthread_join(tinfo[tnum].thread_id, &res);
        if (s != 0)
            handle_error_en(s, "pthread_join");

        printf("Joined with thread %d; returned value was %s\n",
               tinfo[tnum].thread_num, (char *) res);
        free(res);      /* Free memory allocated by thread */
    }

    free(tinfo);
    exit(EXIT_SUCCESS);
}
示例#25
0
int threadingDaemonStart (const int listening_port, 
                          const int max_clients, 
                          int read_chunk_size,
                          int write_chunk_size,
                          int (* net_thread_active_io_func)(buffer_state_t *, buffer_state_t *, void **),
                          int (* net_thread_idle_io_func)(buffer_state_t *, void **),
                          int (* net_thread_state_initiator_func)(void **, void *),
                          void * net_thread_state_initiator_arg,
                          int (* net_thread_state_liberator_func)(void **))
{
    int                         active_thread_counter = 0;
    int                         master_socket         = -1;
    int                         connection_fd         = -1;
    pthread_attr_t              attr;
    size_t                      stacksize             = 0;
    char *                      remote_host           = NULL;
    int                         rc                    = 0;
    net_thread_pool_t *         net_thread_pool       = NULL;
    net_thread_pool_t *         net_thread_pool_node  = NULL;
    net_thread_pool_t *         net_thread_looper     = NULL;


    pthread_attr_init(&attr);
    pthread_attr_getstacksize (&attr, &stacksize);
    printf("Default stack size = %li\n", stacksize);
    stacksize = sizeof(double)*1000000+1000000;

    printf("Amount of stack needed per thread = %li\n",stacksize);
    pthread_attr_setstacksize (&attr, stacksize); 

    /* Create an IPv4/IPv6 service socket for the commander */
    master_socket = createAndSetUpATCPServerSocket (listening_port, max_clients);
    if (master_socket < 0)
    {
        return -1;
    }

    scar_log (1, "Listening on port %d\n", listening_port);


    /* Connection handler */
    while (1)
    {
        connection_fd = net_accept_new_client_socket (master_socket, &remote_host);
        if (connection_fd < 0)
        {
            scar_log (1, "%S: Error: failure in client accept.\n");
            continue;
        }

        net_thread_pool_node = malloc (sizeof (net_thread_pool_t));
        net_thread_pool_node -> next                                                      = NULL;
        net_thread_pool_node -> net_thread_parameters.client_fd                           = connection_fd;
        if (read_chunk_size <= 0)
            net_thread_pool_node -> net_thread_parameters.read_byte_size                  = 1024;
        else
            net_thread_pool_node -> net_thread_parameters.read_byte_size                  = read_chunk_size;
        if (write_chunk_size <= 0)
            net_thread_pool_node -> net_thread_parameters.write_byte_size                 = 1024;
        else
            net_thread_pool_node -> net_thread_parameters.write_byte_size                 = write_chunk_size;
        net_thread_pool_node -> net_thread_parameters.hostname                            = remote_host;
        net_thread_pool_node -> net_thread_parameters.net_thread_active_io_func           = net_thread_active_io_func;
        net_thread_pool_node -> net_thread_parameters.net_thread_idle_io_func             = net_thread_idle_io_func;
        net_thread_pool_node -> net_thread_parameters.net_thread_state_initiator_func     = net_thread_state_initiator_func;
        net_thread_pool_node -> net_thread_parameters.net_thread_state_initiator_arg      = net_thread_state_initiator_arg;
        net_thread_pool_node -> net_thread_parameters.net_thread_state_liberator_func     = net_thread_state_liberator_func; 

        scar_log (1, "Got connection from: %s\n", remote_host);

        /* start client thread */
        rc = pthread_create(&(net_thread_pool_node -> threadid), &attr, threadingDaemonClientHandler, (void*)(&net_thread_pool_node));
        if (rc != 0)
        {
            scar_log (1, "%s: Failed to spawn thread. To bad for this client.\n", __func__);
            /* Liberate the memory and close the file descriptor */
            liberate_net_thread_pool_node (net_thread_pool_node, 1);
        }


        /* All is well, client network thread launched  - register the Thread information in the pool */
        if (net_thread_pool == NULL)
            net_thread_pool = net_thread_pool_node;
        else
        {
            net_thread_looper = net_thread_pool;
            while (net_thread_looper -> next != NULL)
            {
                net_thread_looper = net_thread_looper -> next;
            }
            net_thread_looper -> next = net_thread_pool_node;
        }

        /* Count active threads */
        active_thread_counter++;
    }

    /* Shutting down master socket */
    shutdown(master_socket, SHUT_RDWR);
    close(master_socket);
    master_socket = -1;

    pthread_exit(NULL);
    return 0;
}
示例#26
0
void *transmitter(void *arg)
{
    struct sched_param  param = { .sched_priority = 80 };
    struct timespec     next_period;
    struct timespec     tx_date;


    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    clock_gettime(CLOCK_MONOTONIC, &next_period);

    while(1) {
        next_period.tv_nsec += cycle * 1000;
        if (next_period.tv_nsec >= 1000000000) {
            next_period.tv_nsec = 0;
            next_period.tv_sec++;
        }

        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_period, NULL);

        clock_gettime(CLOCK_MONOTONIC, &tx_date);

        /* transmit the request packet containing the local time */
        if (sendto(sock, &tx_date, sizeof(tx_date), 0,
                   (struct sockaddr *)&dest_addr,
                   sizeof(struct sockaddr_in)) < 0) {
            if (errno == EBADF)
                printf("terminating transmitter thread\n");
            else
                perror("sendto failed");
            return NULL;
        }
    }
}


void *receiver(void *arg)
{
    struct sched_param  param = { .sched_priority = 82 };
    struct msghdr       msg;
    struct iovec        iov;
    struct sockaddr_in  addr;
    struct timespec     rx_date;
    struct packet_stats stats;
    int                 ret;


    msg.msg_name       = &addr;
    msg.msg_namelen    = sizeof(addr);
    msg.msg_iov        = &iov;
    msg.msg_iovlen     = 1;
    msg.msg_control    = NULL;
    msg.msg_controllen = 0;

    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    while (1) {
        iov.iov_base = &packet;
        iov.iov_len  = sizeof(packet);

        ret = recvmsg(sock, &msg, 0);
        if (ret <= 0) {
            printf("terminating receiver thread\n");
            return NULL;
        }

        clock_gettime(CLOCK_MONOTONIC, &rx_date);
        stats.rtt = rx_date.tv_sec * 1000000000LL + rx_date.tv_nsec;
        stats.rtt -= packet.tx_date.tv_sec * 1000000000LL +
            packet.tx_date.tv_nsec;
        stats.addr = addr.sin_addr;

        mq_send(mq, (char *)&stats, sizeof(stats), 0);
    }
}


void catch_signal(int sig)
{
    mq_close(mq);
}


int main(int argc, char *argv[])
{
    struct sched_param param = { .sched_priority = 1 };
    struct sockaddr_in local_addr;
    int add_rtskbs = 30;
    pthread_attr_t thattr;
    char mqname[16];
    struct mq_attr mqattr;
    int stations = 0;
    int ret;


    while (1) {
        switch (getopt(argc, argv, "d:l:c:")) {
            case 'd':
                dest_ip_s = optarg;
                break;

            case 'l':
                local_ip_s = optarg;
                break;

            case 'c':
                cycle = atoi(optarg);
                break;

            case -1:
                goto end_of_opt;

            default:
                printf("usage: %s [-d <dest_ip>] [-l <local_ip>] "
                       "[-c <cycle_microsecs>]\n", argv[0]);
                return 0;
        }
    }
 end_of_opt:

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port   = htons(XMT_PORT);
    if (dest_ip_s[0])
        inet_aton(dest_ip_s, &dest_addr.sin_addr);
    else
        dest_addr.sin_addr.s_addr = INADDR_ANY;

    if (local_ip_s[0])
        inet_aton(local_ip_s, &local_addr.sin_addr);
    else
        local_addr.sin_addr.s_addr = INADDR_ANY;

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    signal(SIGHUP, catch_signal);
    mlockall(MCL_CURRENT|MCL_FUTURE);

    printf("destination ip address: %s = %08x\n",
           dest_ip_s[0] ? dest_ip_s : "SENDER", dest_addr.sin_addr.s_addr);
    printf("local ip address: %s = %08x\n",
           local_ip_s[0] ? local_ip_s : "INADDR_ANY", local_addr.sin_addr.s_addr);
    printf("cycle: %d us\n", cycle);

    /* create rt-socket */
    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        perror("socket cannot be created");
        return 1;
    }

    /* bind the rt-socket to local_addr */
    local_addr.sin_family = AF_INET;
    local_addr.sin_port   = htons(RCV_PORT);
    if ((ret = bind(sock, (struct sockaddr *)&local_addr,
                    sizeof(struct sockaddr_in))) < 0) {
        close(sock);
        perror("cannot bind to local ip/port");
        return 1;
    }

    /* extend the socket pool */
    ret = ioctl(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != add_rtskbs)
        printf("WARNING: ioctl(RTNET_RTIOC_EXTPOOL) = %d\n", ret);

    /* create statistic message queue */
    snprintf(mqname, sizeof(mqname), "rtt-sender-%d", getpid());
    mqattr.mq_flags   = 0;
    mqattr.mq_maxmsg  = 100;
    mqattr.mq_msgsize = sizeof(struct packet_stats);
    mqattr.mq_curmsgs = 0;
    mq = mq_open(mqname, O_RDWR | O_CREAT | O_EXCL, 0600, &mqattr);
    if (mq == (mqd_t)-1) {
        perror("opening mqueue failed");
        close(sock);
        return 1;
    }

    /* create transmitter rt-thread */
    pthread_attr_init(&thattr);
    pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setstacksize(&thattr, PTHREAD_STACK_MIN);
    ret = pthread_create(&recv_thread, &thattr, &receiver, NULL);
    if (ret) {
        errno = ret; perror("pthread_create(receiver) failed");
        close(sock);
        mq_close(mq);
        return 1;
    }

    /* create receiver rt-thread */
    ret = pthread_create(&xmit_thread, &thattr, &transmitter, NULL);
    if (ret) {
        errno = ret; perror("pthread_create(transmitter) failed");
        close(sock);
        mq_close(mq);
        pthread_kill(recv_thread, SIGHUP);
        pthread_join(recv_thread, NULL);
        return 1;
    }

    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

    while (1) {
        struct packet_stats pack;
        struct station_stats *pstat;
        int nr;

        ret = mq_receive(mq, (char *)&pack, sizeof(pack), NULL);
        if (ret < (int)sizeof(pack))
            break;

        pstat = lookup_stats(pack.addr);
        if (!pstat)
            continue;

        pstat->last = pack.rtt;
        if (pstat->last < pstat->min)
            pstat->min = pstat->last;
        if (pstat->last > pstat->max)
            pstat->max = pstat->last;
        pstat->count++;

        nr = pstat - &station[0];
        if (nr >= stations) {
            stations = nr+1;
            printf("\n");
        }

        printf("\033[%dA%s\t%9.3f us, min=%9.3f us, max=%9.3f us, count=%ld\n",
               stations-nr, inet_ntoa(pack.addr), (float)pstat->last/1000,
               (float)pstat->min/1000, (float)pstat->max/1000, pstat->count);
        for (nr = stations-nr-1; nr > 0; nr --)
            printf("\n");
    }

    /* This call also leaves primary mode, required for socket cleanup. */
    printf("shutting down\n");

    /* Important: First close the socket! */
    while ((close(sock) < 0) && (errno == EAGAIN)) {
        printf("socket busy - waiting...\n");
        sleep(1);
    }

    pthread_join(xmit_thread, NULL);
    pthread_kill(recv_thread, SIGHUP);
    pthread_join(recv_thread, NULL);

    return 0;
}
示例#27
0
文件: main.c 项目: Scrik/netdata
int main(int argc, char **argv)
{
	int i;
	int config_loaded = 0;
	int dont_fork = 0;
	size_t wanted_stacksize = 0, stacksize = 0;
	pthread_attr_t attr;

	// global initialization
	get_HZ();

	// set the name for logging
	program_name = "netdata";

	// parse command line.

	// parse depercated options
	// TODO: Remove this block with the next major release.
	{
		i = 1;
		while(i < argc) {
			if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) {
				strncpyz(pidfile, argv[i+1], FILENAME_MAX);
				fprintf(stderr, "%s: deprecate option -- %s -- please use -P instead.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) {
				dont_fork = 1;
				fprintf(stderr, "%s: deprecate option -- %s -- please use -D instead.\n ", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) {
				config_set("global", "host access prefix", argv[i+1]);
				fprintf(stderr, "%s: deprecate option -- %s -- please use -s instead.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) {
				config_set("global", "history", argv[i+1]);
				fprintf(stderr, "%s: deprecate option -- %s -- This option will be rmoved with V2.*.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else i++;
		}
	}

	// parse options
	{
		int num_opts = sizeof(options) / sizeof(struct option_def);
		char optstring[(num_opts * 2) + 1];

		int string_i = 0;
		for( i = 0; i < num_opts; i++ ) {
			optstring[string_i] = options[i].val;
			string_i++;
			if(options[i].arg_name) {
				optstring[string_i] = ':';
				string_i++;
			}
		}

		int opt;
		while( (opt = getopt(argc, argv, optstring)) != -1 ) {
			switch(opt) {
				case 'c':
					if(load_config(optarg, 1) != 1) {
						error("Cannot load configuration file %s.", optarg);
						exit(1);
					}
					else {
						debug(D_OPTIONS, "Configuration loaded from %s.", optarg);
						config_loaded = 1;
					}
					break;
				case 'D':
					dont_fork = 1;
					break;
				case 'h':
					help(0);
					break;
				case 'i':
					config_set("global", "bind socket to IP", optarg);
					break;
				case 'P':
					strncpy(pidfile, optarg, FILENAME_MAX);
					pidfile[FILENAME_MAX] = '\0';
					break;
				case 'p':
					config_set("global", "port", optarg);
					break;
				case 's':
					config_set("global", "host access prefix", optarg);
					break;
				case 't':
					config_set("global", "update every", optarg);
					break;
				case 'u':
					config_set("global", "run as user", optarg);
					break;
				case 'v':
					// TODO: Outsource version to makefile which can compute version from git.
					printf("netdata 1.1.0\n");
					return 0;
					break;
				case 'W': 
					{
						char* stacksize = "stacksize=";
						char* debug_flags_string = "debug_flags=";
						if(strcmp(optarg, "unittest") == 0) {
							rrd_update_every = 1;
							if(run_all_mockup_tests()) exit(1);
							if(unit_test_storage()) exit(1);
							fprintf(stderr, "\n\nALL TESTS PASSED\n\n");
							exit(0);
						} else if(strncmp(optarg, stacksize, strlen(stacksize)) == 0) {
							optarg += strlen(stacksize);
							config_set("global", "pthread stack size", optarg);
						} else if(strncmp(optarg, debug_flags_string, strlen(debug_flags_string)) == 0) {
							optarg += strlen(debug_flags_string);
							config_set("global", "debug flags",  optarg);
							debug_flags = strtoull(optarg, NULL, 0);
						}
					}
					break;
				default: /* ? */
					help(1);
					break;
			}
		} 
	}

	if(!config_loaded) load_config(NULL, 0);

	// prepare configuration environment variables for the plugins
	setenv("NETDATA_CONFIG_DIR" , config_get("global", "config directory"   , CONFIG_DIR) , 1);
	setenv("NETDATA_PLUGINS_DIR", config_get("global", "plugins directory"  , PLUGINS_DIR), 1);
	setenv("NETDATA_WEB_DIR"    , config_get("global", "web files directory", WEB_DIR)    , 1);
	setenv("NETDATA_CACHE_DIR"  , config_get("global", "cache directory"    , CACHE_DIR)  , 1);
	setenv("NETDATA_LIB_DIR"    , config_get("global", "lib directory"      , VARLIB_DIR) , 1);
	setenv("NETDATA_LOG_DIR"    , config_get("global", "log directory"      , LOG_DIR)    , 1);
	setenv("NETDATA_HOST_PREFIX", config_get("global", "host access prefix" , "")         , 1);
	setenv("HOME"               , config_get("global", "home directory"     , CACHE_DIR)  , 1);

	// avoid extended to stat(/etc/localtime)
	// http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
	setenv("TZ", ":/etc/localtime", 0);

	// cd to /tmp to avoid any plugins writing files at random places
	if(chdir("/tmp")) error("netdata: ERROR: Cannot cd to /tmp");

	char *input_log_file = NULL;
	char *output_log_file = NULL;
	char *error_log_file = NULL;
	char *access_log_file = NULL;
	char *user = NULL;
	{
		char buffer[1024];

		// --------------------------------------------------------------------

		sprintf(buffer, "0x%08llx", 0ULL);
		char *flags = config_get("global", "debug flags", buffer);
		setenv("NETDATA_DEBUG_FLAGS", flags, 1);

		debug_flags = strtoull(flags, NULL, 0);
		debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);

		if(debug_flags != 0) {
			struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
			if(setrlimit(RLIMIT_CORE, &rl) != 0)
				info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
		}

		// --------------------------------------------------------------------

#ifdef MADV_MERGEABLE
		enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm);
#else
#warning "Kernel memory deduplication (KSM) is not available"
#endif

		// --------------------------------------------------------------------


		global_host_prefix = config_get("global", "host access prefix", "");
		setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);

		// --------------------------------------------------------------------

		output_log_file = config_get("global", "debug log", LOG_DIR "/debug.log");
		if(strcmp(output_log_file, "syslog") == 0) {
			output_log_syslog = 1;
			output_log_file = NULL;
		}
		else if(strcmp(output_log_file, "none") == 0) {
			output_log_syslog = 0;
			output_log_file = NULL;
		}
		else output_log_syslog = 0;

		// --------------------------------------------------------------------

		error_log_file = config_get("global", "error log", LOG_DIR "/error.log");
		if(strcmp(error_log_file, "syslog") == 0) {
			error_log_syslog = 1;
			error_log_file = NULL;
		}
		else if(strcmp(error_log_file, "none") == 0) {
			error_log_syslog = 0;
			error_log_file = NULL;
			// optimization - do not even generate debug log entries
		}
		else error_log_syslog = 0;

		error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period);
		setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period"    , ""), 1);

		error_log_errors_per_period = config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period);
		setenv("NETDATA_ERRORS_PER_PERIOD"     , config_get("global", "errors to trigger flood protection", ""), 1);

		// --------------------------------------------------------------------

		access_log_file = config_get("global", "access log", LOG_DIR "/access.log");
		if(strcmp(access_log_file, "syslog") == 0) {
			access_log_syslog = 1;
			access_log_file = NULL;
		}
		else if(strcmp(access_log_file, "none") == 0) {
			access_log_syslog = 0;
			access_log_file = NULL;
		}
		else access_log_syslog = 0;

		// --------------------------------------------------------------------

		rrd_memory_mode = rrd_memory_mode_id(config_get("global", "memory mode", rrd_memory_mode_name(rrd_memory_mode)));

		// --------------------------------------------------------------------

		if(gethostname(buffer, HOSTNAME_MAX) == -1)
			error("WARNING: Cannot get machine hostname.");
		hostname = config_get("global", "hostname", buffer);
		debug(D_OPTIONS, "hostname set to '%s'", hostname);

		// --------------------------------------------------------------------

		rrd_default_history_entries = (int) config_get_number("global", "history", RRD_DEFAULT_HISTORY_ENTRIES);
		if(rrd_default_history_entries < 5 || rrd_default_history_entries > RRD_HISTORY_ENTRIES_MAX) {
			info("Invalid save lines %d given. Defaulting to %d.", rrd_default_history_entries, RRD_DEFAULT_HISTORY_ENTRIES);
			rrd_default_history_entries = RRD_DEFAULT_HISTORY_ENTRIES;
		}
		else {
			debug(D_OPTIONS, "save lines set to %d.", rrd_default_history_entries);
		}

		// --------------------------------------------------------------------

		rrd_update_every = (int) config_get_number("global", "update every", UPDATE_EVERY);
		if(rrd_update_every < 1 || rrd_update_every > 600) {
			info("Invalid update timer %d given. Defaulting to %d.", rrd_update_every, UPDATE_EVERY_MAX);
			rrd_update_every = UPDATE_EVERY;
		}
		else debug(D_OPTIONS, "update timer set to %d.", rrd_update_every);

		// let the plugins know the min update_every
		{
			char buf[51];
			snprintfz(buf, 50, "%d", rrd_update_every);
			setenv("NETDATA_UPDATE_EVERY", buf, 1);
		}

		// --------------------------------------------------------------------

		// block signals while initializing threads.
		// this causes the threads to block signals.
		sigset_t sigset;
		sigfillset(&sigset);

		if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1) {
			error("Could not block signals for threads");
		}

		// Catch signals which we want to use to quit savely
		struct sigaction sa;
		sigemptyset(&sa.sa_mask);
		sigaddset(&sa.sa_mask, SIGHUP);
		sigaddset(&sa.sa_mask, SIGINT);
		sigaddset(&sa.sa_mask, SIGTERM);
		sa.sa_handler = sig_handler;
		sa.sa_flags = 0;
		if(sigaction(SIGHUP, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGHUP");
		}
		if(sigaction(SIGINT, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGINT");
		}
		if(sigaction(SIGTERM, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGTERM");
		}
		// Ignore SIGPIPE completely.
		// INFO: If we add signals here we have to unblock them
		// at popen.c when running a external plugin.
		sa.sa_handler = SIG_IGN;
		if(sigaction(SIGPIPE, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGTERM");
		}

		// --------------------------------------------------------------------

		i = pthread_attr_init(&attr);
		if(i != 0)
			fatal("pthread_attr_init() failed with code %d.", i);

		i = pthread_attr_getstacksize(&attr, &stacksize);
		if(i != 0)
			fatal("pthread_attr_getstacksize() failed with code %d.", i);
		else
			debug(D_OPTIONS, "initial pthread stack size is %zu bytes", stacksize);

		wanted_stacksize = config_get_number("global", "pthread stack size", stacksize);

		// --------------------------------------------------------------------

		for (i = 0; static_threads[i].name != NULL ; i++) {
			struct netdata_static_thread *st = &static_threads[i];

			if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled);
			if(st->enabled && st->init_routine) st->init_routine();
		}

		// --------------------------------------------------------------------

		// get the user we should run
		// IMPORTANT: this is required before web_files_uid()
		user = config_get("global", "run as user"    , (getuid() == 0)?NETDATA_USER:"");

		// IMPORTANT: these have to run once, while single threaded
		web_files_uid(); // IMPORTANT: web_files_uid() before web_files_gid()
		web_files_gid();

		// --------------------------------------------------------------------

		listen_backlog = (int) config_get_number("global", "http port listen backlog", LISTEN_BACKLOG);

		listen_port = (int) config_get_number("global", "port", LISTEN_PORT);
		if(listen_port < 1 || listen_port > 65535) {
			info("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT);
			listen_port = LISTEN_PORT;
		}
		else debug(D_OPTIONS, "Listen port set to %d.", listen_port);

		int ip = 0;
		char *ipv = config_get("global", "ip version", "any");
		if(!strcmp(ipv, "any") || !strcmp(ipv, "both") || !strcmp(ipv, "all")) ip = 0;
		else if(!strcmp(ipv, "ipv4") || !strcmp(ipv, "IPV4") || !strcmp(ipv, "IPv4") || !strcmp(ipv, "4")) ip = 4;
		else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
		else info("Cannot understand ip version '%s'. Assuming 'any'.", ipv);

		if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
		if(listen_fd < 0) {
			listen_fd = create_listen_socket4(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
			if(listen_fd >= 0 && ip != 4) info("Managed to open an IPv4 socket on port %d.", listen_port);
		}

		if(listen_fd < 0) fatal("Cannot listen socket.");
	}

	// never become a problem
	if(nice(20) == -1) error("Cannot lower my CPU priority.");

	if(become_daemon(dont_fork, 0, user, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1)
		fatal("Cannot demonize myself.");

#ifdef NETDATA_INTERNAL_CHECKS
	if(debug_flags != 0) {
		struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
		if(setrlimit(RLIMIT_CORE, &rl) != 0)
			info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
		prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
	}
#endif /* NETDATA_INTERNAL_CHECKS */

	if(output_log_syslog || error_log_syslog || access_log_syslog)
		openlog("netdata", LOG_PID, LOG_DAEMON);

	info("NetData started on pid %d", getpid());


	// ------------------------------------------------------------------------
	// get default pthread stack size

	if(stacksize < wanted_stacksize) {
		i = pthread_attr_setstacksize(&attr, wanted_stacksize);
		if(i != 0)
			fatal("pthread_attr_setstacksize() to %zu bytes, failed with code %d.", wanted_stacksize, i);
		else
			info("Successfully set pthread stacksize to %zu bytes", wanted_stacksize);
	}

	// --------------------------------------------------------------------
	// initialize the registry

	registry_init();

	// ------------------------------------------------------------------------
	// spawn the threads

	for (i = 0; static_threads[i].name != NULL ; i++) {
		struct netdata_static_thread *st = &static_threads[i];

		if(st->enabled) {
			st->thread = malloc(sizeof(pthread_t));
			if(!st->thread)
				fatal("Cannot allocate pthread_t memory");

			info("Starting thread %s.", st->name);

			if(pthread_create(st->thread, &attr, st->start_routine, NULL))
				error("failed to create new thread for %s.", st->name);

			else if(pthread_detach(*st->thread))
				error("Cannot request detach of newly created %s thread.", st->name);
		}
		else info("Not starting thread %s.", st->name);
	}

	// ------------------------------------------------------------------------
	// block signals while initializing threads.
	sigset_t sigset;
	sigfillset(&sigset);

	if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
		error("Could not unblock signals for threads");
	}

	// Handle flags set in the signal handler.
	while(1) {
		pause();
		if(netdata_exit) {
			info("Exit main loop of netdata.");
			netdata_cleanup_and_exit(0);
			exit(0);
		}
	}
}
示例#28
0
/*
 * pj_thread_create(...)
 */
PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool, 
				      const char *thread_name,
				      pj_thread_proc *proc, 
				      void *arg,
				      pj_size_t stack_size, 
				      unsigned flags,
				      pj_thread_t **ptr_thread)
{
#if PJ_HAS_THREADS
    pj_thread_t *rec;
    pthread_attr_t thread_attr;
    void *stack_addr;
    int rc;

    PJ_UNUSED_ARG(stack_addr);

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(pool && proc && ptr_thread, PJ_EINVAL);

    /* Create thread record and assign name for the thread */
    rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));
    PJ_ASSERT_RETURN(rec, PJ_ENOMEM);
    
    /* Set name. */
    if (!thread_name) 
	thread_name = "thr%p";
    
    if (strchr(thread_name, '%')) {
	pj_ansi_snprintf(rec->obj_name, PJ_MAX_OBJ_NAME, thread_name, rec);
    } else {
	strncpy(rec->obj_name, thread_name, PJ_MAX_OBJ_NAME);
	rec->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
    }

    /* Set default stack size */
    if (stack_size == 0)
	stack_size = PJ_THREAD_DEFAULT_STACK_SIZE;

#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
    rec->stk_size = stack_size;
    rec->stk_max_usage = 0;
#endif

    /* Emulate suspended thread with mutex. */
    if (flags & PJ_THREAD_SUSPENDED) {
	rc = pj_mutex_create_simple(pool, NULL, &rec->suspended_mutex);
	if (rc != PJ_SUCCESS) {
	    return rc;
	}

	pj_mutex_lock(rec->suspended_mutex);
    } else {
	pj_assert(rec->suspended_mutex == NULL);
    }
    

    /* Init thread attributes */
    pthread_attr_init(&thread_attr);

#if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0
    /* Set thread's stack size */
    rc = pthread_attr_setstacksize(&thread_attr, stack_size);
    if (rc != 0)
	return PJ_RETURN_OS_ERROR(rc);
#endif	/* PJ_THREAD_SET_STACK_SIZE */


#if defined(PJ_THREAD_ALLOCATE_STACK) && PJ_THREAD_ALLOCATE_STACK!=0
    /* Allocate memory for the stack */
    stack_addr = pj_pool_alloc(pool, stack_size);
    PJ_ASSERT_RETURN(stack_addr, PJ_ENOMEM);

    rc = pthread_attr_setstackaddr(&thread_attr, stack_addr);
    if (rc != 0)
	return PJ_RETURN_OS_ERROR(rc);
#endif	/* PJ_THREAD_ALLOCATE_STACK */


    /* Create the thread. */
    rec->proc = proc;
    rec->arg = arg;
    rc = pthread_create( &rec->thread, &thread_attr, &thread_main, rec);
    if (rc != 0) {
	return PJ_RETURN_OS_ERROR(rc);
    }

    *ptr_thread = rec;

    PJ_LOG(6, (rec->obj_name, "Thread created"));
    return PJ_SUCCESS;
#else
    pj_assert(!"Threading is disabled!");
    return PJ_EINVALIDOP;
#endif
}
示例#29
0
int main(int ac,
         char **av) {
  int             opt;
  size_t          num_threads = DEFAULT_NUM_THREADS;
  size_t          stack_size = DEFAULT_STACK_SIZE;
  char const      **line;
  int             rv = 0;
  pthread_t       thr_state;
  pthread_attr_t  attr;
  size_t          tid;

  while (EOF != (opt = getopt(ac, av, "fhn:s:v"))) {
    switch (opt) {
      case 'f':
        gExpectThreadCreationFailure = 1;
        break;
      case 'n':
        num_threads = strtoul(optarg, (char **) NULL, 0);
        break;
      case 's':
        stack_size = strtoul(optarg, (char **) NULL, 0);
        break;
      case 'v':
        ++gVerbosity;
        break;
      case 'h':
        fprintf(stderr, "%s%s\n", short_usage, flags_usage);
        for (line = long_winded_explanation; NULL != *line; ++line) {
          fprintf(stderr, "       %s\n", *line);
        }
        return 0;
      default:
        fprintf(stderr, "%s\n", short_usage);
        return 1;
    }
  }

  if (gVerbosity > 1) {
    printf("Creating %"PRIdS" threads with 0x%"PRIxS" byte stacks\n",
           num_threads,
           stack_size);
    printf("According to the command line parameters,"
           " this is%s expected to work.\n",
           gExpectThreadCreationFailure ? " not" : "");
  }

  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr, stack_size);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  for (tid = 0; tid < num_threads; ++tid) {
    if (gVerbosity > 0) {
      printf("Creating thread %"PRIdS"\n", tid); fflush(stdout);
    }
    /*
     * thr_state is overwritten each time.
     */
    if (0 != (rv = pthread_create(&thr_state,
                                  &attr,
                                  thread_start,
                                  (void *) tid))) {
      printf("Thread creation failed at thread %"PRIdS", error %d (%s)\n",
             tid, rv, strerror(rv));
      if (gExpectThreadCreationFailure) {
        if (EAGAIN == rv) {
          printf("This is expected.\n");
          rv = 0;
          goto cleanup_exit;
        }
        /*
         * Anything other than EAGAIN is bad.
         */
      }
      break;
    }
    putchar('.');
    if (kCountMask == (tid & kCountMask)) {
      printf("%"PRIdS, tid);
    }
    if (kNewlineMask == (tid & kNewlineMask)) {
      putchar('\n');
    }
  }
  if (0 == rv && gExpectThreadCreationFailure) {
    printf("Expected thread creation failure.\n");
    rv = 1;
  }
cleanup_exit:
  pthread_mutex_lock(&gBarrierMu);
  gThreadWait = 0;
  pthread_cond_broadcast(&gBarrierCv);
  pthread_mutex_unlock(&gBarrierMu);

  if (0 == rv) {
    printf("PASSED\n");
  } else {
    printf("FAILED\n");
  }

  return rv;
}
示例#30
0
文件: timer1.c 项目: 0xCA5A/dd-wrt
int main(int argc, char **argv)
{
    int ret;
    sigset_t mask;
    pthread_attr_t attr;
    void *retval;
    
    CYG_TEST_INIT();

    // Make a full signal set
    sigfillset( &mask );

    
    // Install signal handlers
    {
        struct sigaction sa;

        sa.sa_sigaction = sigusr1;
        sa.sa_mask = mask;
        sa.sa_flags = SA_SIGINFO;

        ret = sigaction( SIGUSR1, &sa, NULL );

        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
    }
    {
        struct sigaction sa;

        sa.sa_sigaction = sigusr2;
        sa.sa_mask = mask;
        sa.sa_flags = SA_SIGINFO;

        ret = sigaction( SIGUSR2, &sa, NULL );

        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
    }


    // Create the timers

    {
        struct sigevent sev;
        struct itimerspec value;
        
        sev.sigev_notify                = SIGEV_SIGNAL;
        sev.sigev_signo                 = SIGUSR1;
        sev.sigev_value.sival_int       = 0xABCDEF01;

        value.it_value.tv_sec           = 1;
        value.it_value.tv_nsec          = 0;
        value.it_interval.tv_sec        = 0;
        value.it_interval.tv_nsec       = 0;
        
        ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );

        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");

        ret = timer_settime( timer1, 0, &value, NULL );

        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
    }

#if 1    
    {
        struct sigevent sev;
        struct itimerspec value;
        
        sev.sigev_notify                = SIGEV_SIGNAL;
        sev.sigev_signo                 = SIGUSR2;
        sev.sigev_value.sival_int       = 0xABCDEF02;

        value.it_value.tv_sec           = 0;
        value.it_value.tv_nsec          = 500000000;
        value.it_interval.tv_sec        = 0;
        value.it_interval.tv_nsec       = 250000000;
        
        ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );

        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");

        ret = timer_settime( timer2, 0, &value, NULL );

        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
    }
#endif    
    
    // Mask all signals
    pthread_sigmask( SIG_SETMASK, &mask, NULL );
    
    sem_init( &sem, 0, 0 );
    
    // Create test threads

    {
        pthread_attr_init( &attr );

        pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
        pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );

        pthread_create( &thread1,
                        &attr,
                        pthread_entry1,
                        (void *)0x12345671);
    }

    {
        pthread_attr_init( &attr );

        pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
        pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );

        pthread_create( &thread2,
                        &attr,
                        pthread_entry2,
                        (void *)0x12345672);
    }
    
    // Wait for other thread to get started
    CYG_TEST_INFO( "Main: calling sem_wait()");
    sem_wait( &sem );
    CYG_TEST_INFO( "Main: calling sem_wait() again");    
    sem_wait( &sem );

    // Now join with thread1
    CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
    pthread_join( thread1, &retval );

    CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
    
    // And thread 2
    CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
    pthread_join( thread2, &retval );

    // now delete the timers
    CYG_TEST_INFO( "Main: calling timer_delete(timer1)");    
    ret = timer_delete( timer1 );

    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");

    CYG_TEST_INFO( "Main: calling timer_delete(timer2)");    
    ret = timer_delete( timer2 );

    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");

    
    CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
    
    CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
    CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );

    CYG_TEST_PASS_FINISH( "timer1" );
}