void* timer_run_thread(void* x) { rtdal_timer_t *obj = (rtdal_timer_t*) x; if (DEBUG_rtdal) { rtdal_task_print_sched(); } switch(obj->mode) { case XENOMAI: #ifdef __XENO__ return xenomai_timer_run_thread(obj); #else aerror("Not compiled with xenomai support\n"); return NULL; #endif case NANOSLEEP: return nanoclock_timer_run_thread(obj); #ifdef EN_TIMERFD case TIMERFD: return timerfd_timer_run_thread(obj); #endif default: aerror_msg("Unknown timer mode %d\n", obj->mode); return NULL; } }
int timer_setup (rtdal_timer_t *info) { long int ns; __time_t sec; int fd; if (info->period<=0) { aerror_msg("Invalid period %d\n", (int) info->period); return -1; } /* Create the timer */ fd = timerfd_create (CLOCK_REALTIME, 0); if (fd == -1) { perror("timerfd_create"); return -1; } info->wakeups_missed = 0; info->timer_fd = fd; /* Make the timer periodic */ sec = info->period/1000000000; ns = (info->period - (sec * 1000000)); info->itval.it_interval.tv_sec = sec; info->itval.it_interval.tv_nsec = ns; info->itval.it_value.tv_sec = sec; info->itval.it_value.tv_nsec = ns; return 0; }
inline static void pipeline_run_time_slot(pipeline_t *obj) { int idx; rtdal_process_t *run_proc; hdebug("pipeid=%d, tslot=%d, nof_process=%d thread=%d\n",obj->id,obj->ts_counter, obj->nof_processes, obj->thread); obj->finished = 0; pipeline_run_thread_print_time(obj); run_proc = obj->first_process; idx = 0; while(run_proc) { hdebug("%d/%d: run=%d code=%d next=0x%x\n",idx,obj->nof_processes,run_proc->runnable, run_proc->finish_code,run_proc->next); if (idx > obj->nof_processes) { aerror_msg("Fatal error. Corrupted pipeline-%d process list at process %d\n", obj->id, idx); kill(getpid(),SIGTERM); pthread_exit(NULL); } pipeline_run_thread_check_status(obj,run_proc); pipeline_run_thread_run_module(obj,run_proc, idx); run_proc = run_proc->next; idx++; } obj->ts_counter++; obj->finished = 1; }
/** USES oesr_man_ERROR to describe any mapping error */ int generate_model(mapping_t *m, waveform_t *waveform, man_platform_t *platform) { int multiplicity; if (waveform->granularity_us) { if (platform->ts_length_us % waveform->granularity_us) { aerror_msg("Timeslot length must be multiple of waveform granularity (%d us)\n", waveform->granularity_us); return -1; } multiplicity = platform->ts_length_us/waveform->granularity_us; } else { multiplicity = 1; } generate_model_platform(platform); generate_model_join_function(waveform); generate_model_c_vector(waveform, multiplicity); generate_model_b_matrix(waveform, multiplicity); generate_model_stages(waveform); return 0; }
/** \brief Processes a packet. Calls one of the processing functions depending on the command */ int nod_anode_dispatch(packet_t *pkt) { int n; ndebug("pkt=0x%x, cmd=%d\n",pkt,packet_get_cmd(pkt)); switch(packet_get_cmd(pkt)) { case CMD_LOAD: n = nod_dispatcher_load(pkt); packet_clear(pkt); break; case CMD_SET: n = nod_dispatcher_set(pkt); packet_clear(pkt); break; case CMD_GET: n = nod_dispatcher_get(pkt); break; case CMD_CONNECT: n = nod_dispatcher_connect_node(pkt); break; case CMD_DISCONNECT: n = nod_dispatcher_disconnect_node(pkt); break; case CMD_HWINFO: n = nod_dispatcher_hwinfo(pkt); break; default: aerror_msg("Unknown command %d\n", (int) packet_get_cmd(pkt)); n = -1; break; } return n; }
/** Maps waveform to the platform. The platform is obtained using the man_platform_get_context() * function. * The mapping result is saved to each module in the module_t.processor_idx and module_t.exec_position * fields. module_t.node is pointed to the platform node object of the allocated processor. * The number of nodes allocated to each node is saved in the mapping_t.modules_x_node array. * \returns 0 if the mapping was feasible, -1 otherwise. The error description is saved in the * oesr_man_error class. */ int mapping_map(mapping_t *m, waveform_t *waveform) { /**@TODO: Use the oesr_man_error class for error messages */ mdebug("waveform_name=%s, nof_modules=%d\n",waveform->name, waveform->nof_modules); int i; int ret=-1; float total_mopts; man_platform_t *platform = man_platform_get_context(); man_node_t *node; if (!platform) { aerror("oesr_man not initialized\n"); return -1; } printf("Computing mapping for %d modules...\n",waveform->nof_modules); if (mapping_alloc(m,waveform->nof_modules,platform->nof_processors)) { return -1; } if (setup_algorithm(m)) { goto free; } if (generate_model(m, waveform, platform)) { goto free; } if (call_algorithm(m, waveform, platform)) { goto free; } total_mopts=0; memset(m->modules_x_node,0,sizeof(int)*MAX(nodes)); for (i=0;i<waveform->nof_modules;i++) { if (m->p_res[joined_function_inv[i]] >= platform->nof_processors) { aerror_msg("Module %d mapped to processor %d, but platform has %d processors only\n", joined_function_inv[i],m->p_res[joined_function_inv[i]]+1,platform->nof_processors); goto free; } man_processor_t *p = (man_processor_t*) platform->processors[m->p_res[joined_function_inv[i]]]; waveform->modules[i].node = p->node; waveform->modules[i].processor_idx = p->idx_in_node; waveform->modules[i].exec_position = i;/*waveform->nof_modules-i-1;*/ node = p->node; m->modules_x_node[node->id]++; total_mopts+=waveform->modules[i].c_mopts[0]; } printf("Done. %g GOPTS\n",total_mopts/1000); ret = 0; free: mapping_free(m,waveform->nof_modules,platform->nof_processors); return ret; }
inline static void pipeline_run_thread_run_module(pipeline_t *pipe, rtdal_process_t *proc, int idx) { hdebug("pipeid=%d, pid=%d, idx=%d, run=%d\n",pipe->id,proc->pid,idx,proc->runnable); if (proc->runnable) { pipe->running_process = proc; pipe->running_process_idx = idx; proc->is_running = 1; if (proc->run_point(proc->arg)) { aerror_msg("Error running module %d:%d\n", pipe->id,pipe->running_process_idx); pipeline_remove(pipe,proc); proc->is_running = 0; } proc->is_running = 0; } }
inline static void pipeline_run_thread_check_status(pipeline_t *pipe, rtdal_process_t *proc) { hdebug("pipeid=%d, pid=%d, run=%d, code=%d, waveform_notify=%d\n",pipe->id,proc->pid, proc->runnable,proc->finish_code, pgroup_notified_failure[proc->attributes.process_group_id]); if (proc->runnable && proc->finish_code != FINISH_OK && !pgroup_notified_failure[proc->attributes.process_group_id]) { if (proc->attributes.finish_callback) { hdebug("calling finish 0x%x arg=0x%x\n",proc->attributes.finish_callback, proc->arg); pgroup_notified_failure[proc->attributes.process_group_id] = 1; rtdal_task_new(NULL, proc->attributes.finish_callback,proc->arg); } else { aerror_msg("Abnormal pid=%d termination but no callback was defined\n", proc->pid); } } }
void* timer_run_thread(void* x) { rtdal_timer_t *obj = (rtdal_timer_t*) x; switch(obj->mode) { case XENOMAI: #ifdef __XENO__ return xenomai_timer_run_thread(obj); #else aerror("Not compiled with xenomai support\n"); return NULL; #endif case NANOSLEEP: return nanoclock_timer_run_thread(obj); default: aerror_msg("Unknown timer mode %d\n", obj->mode); return NULL; } }
/** Called when there is an rtfault in the pipeline */ int pipeline_rt_fault(pipeline_t *obj) { #ifdef KILL_RT_FAULT hdebug("pipeline_id=%d, process_idx=%d\n",obj->id,obj->running_process_idx,obj->running_process_idx); obj->finished = 1; aerror_msg("RT-Fault detected at pipeline %d, process %d\n",obj->id, obj->running_process_idx); if (obj->thread) { int s = pthread_kill(obj->thread,SIGUSR1); if (s) { rtdal_POSERROR(s, "pthread_kill"); return -1; } } #else obj->finished = 1; printf("+++[ts=%d]+++ RT-Fault: Process %d/%d still running in pipeline %d\n", obj->ts_counter, obj->running_process_idx, obj->nof_processes, obj->id); #endif return 0; }
int parse_config(char *config_file) { config_t config; int ret = -1; config_setting_t *rtdal,*dac; const char *tmp; int single_timer; int time_slot_us; config_init(&config); if (!config_read_file(&config, config_file)) { aerror_msg("line %d - %s: \n", config_error_line(&config), config_error_text(&config)); goto destroy; } rtdal = config_lookup(&config, "rtdal"); if (!rtdal) { aerror("Error parsing config file: rtdal section not found.\n"); goto destroy; } if (!config_setting_lookup_int(rtdal, "time_slot_us", &time_slot_us)) { aerror("time_slot_us field not defined\n"); goto destroy; } if (!config_setting_lookup_string(rtdal, "cores", &tmp)) { aerror("cores field not defined\n"); goto destroy; } nof_cores = parse_cores((char*) tmp); if (nof_cores < 0) { printf("Error invalid cores %s\n",tmp); exit(0); } if (!config_setting_lookup_bool(rtdal, "enable_usrp", &using_uhd)) { aerror("enable_usrp field not defined\n"); goto destroy; } if (!config_setting_lookup_bool(rtdal, "timer_mode_single", &single_timer)) { aerror("timer_mode_single field not defined\n"); goto destroy; } if (using_uhd) { if (single_timer) { clock_source = SINGLE_TIMER; } else { clock_source = DAC; } } else { if (single_timer) { clock_source = SINGLE_TIMER; } else { clock_source = MULTI_TIMER; } } if (!config_setting_lookup_string(rtdal, "path_to_libs", &tmp)) { aerror("path_to_libs field not defined\n"); goto destroy; } strcpy(libs_path,tmp); if (using_uhd) { dac = config_lookup(&config, "dac"); if (!dac) { aerror("Error parsing config file: dac section not found.\n"); goto destroy; } #ifdef HAVE_UHD double tmp; if (!config_setting_lookup_float(dac, "samp_freq", &dac_cfg.inputFreq)) { aerror("samp_freq field not defined\n"); goto destroy; } dac_cfg.outputFreq = dac_cfg.inputFreq; if (!config_setting_lookup_float(dac, "rf_freq", &dac_cfg.inputRFFreq)) { aerror("rf_freq field not defined\n"); goto destroy; } dac_cfg.outputRFFreq = dac_cfg.inputRFFreq; if (!config_setting_lookup_float(dac, "rf_gain", &tmp)) { aerror("rf_gain field not defined\n"); goto destroy; } dac_cfg.tx_gain = tmp; dac_cfg.rx_gain = tmp; if (!config_setting_lookup_float(dac, "if_bw", &tmp)) { aerror("rf_gain field not defined\n"); goto destroy; } dac_cfg.tx_bw = tmp; dac_cfg.rx_bw = tmp; if (!config_setting_lookup_bool(dac, "sample_is_short", &dac_cfg.sampleType)) { aerror("rf_gain field not defined\n"); goto destroy; } if (!config_setting_lookup_int(dac, "block_size", &dac_cfg.NsamplesIn)) { aerror("block_size field not defined\n"); goto destroy; } dac_cfg.NsamplesOut = dac_cfg.NsamplesIn; if (!config_setting_lookup_bool(dac, "chain_is_tx", &dac_cfg.chain_is_tx)) { aerror("chain_is_tx field not defined\n"); goto destroy; } dac_cfg.sampleType = 0; dac_cfg.nof_channels = 1; uhd_readcfg(&dac_cfg); #endif } if (using_uhd) { #ifdef HAVE_UHD timeslot_us = (long int) 1000000*((float) dac_cfg.NsamplesOut/dac_cfg.outputFreq); #endif } else { timeslot_us = time_slot_us; } ret=0; destroy: config_destroy(&config); return ret; }