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; }
/*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; }
/** * 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 }
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); }
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); }
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, ¶m); 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; }
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; } }
//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; }
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 }
// 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; }
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; } }
/* 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); } }
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; }
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"); }
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; }
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; }
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; }
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; }
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); }
/***** 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"); } }
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; }
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; }
/* 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 }
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); }
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; }
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, ¶m); 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, ¶m); 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, ¶m); 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; }
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); } } }
/* * 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 }
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; }
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" ); }