示例#1
0
void launch_manual()
{
    char command[512];
    char *manual_file = find_manual_file();

    if (!manual_file) {
        fprintf(stderr, "No manual found.\n");
        return;
    }

#ifdef __APPLE__
    snprintf(command, sizeof(command), "%s/%s", get_data_dir(), manual_file);

    void open_file_with_browser_mac(char *file);

    open_file_with_browser_mac(command);
#else
    	switch (arch) {
        case ARCH_WETAB:
            snprintf(command, sizeof(command),
                "tiitoo-browser-bin -t file://%s/%s",
                get_data_dir(), manual_file);
            break;

        case ARCH_WIN32:
        case ARCH_WIN64:
            snprintf(command, sizeof(command),
                "%s", manual_file);
            break;

        default:
            if (!strcmp(options_browser, "browser")) {
                strcpy(options_browser, "./browser.sh");
            }
            snprintf(command, sizeof(command),
                "%s file://%s/%s",
                options_browser, get_data_dir(), manual_file);
            break;
    }

    launch_command(command);
#endif
}
示例#2
0
void show_history(char * historyfile) {
	  char workstring[1024];
	  // build the browser call string
#ifdef __APPLE__
	  sprintf(workstring,"%s/html/%s",file_name,historyfile);

	  void open_file_with_browser_mac(char *file);

	  open_file_with_browser_mac(workstring);
#else

#ifdef USE_WIN
	  sprintf(workstring,"%s/html/%s",file_name,historyfile);
#else
	  char callstring[1024];
	  get_browser(callstring);
	  sprintf(workstring," %s%s/html/%s",callstring,file_name,historyfile);
#endif
	  launch_command(workstring);
#endif
}
示例#3
0
/*
@desc Prints collected data to an output file, and
manages benchmark execution.
@input
	int pid -- child process id
@errors
	print_data will terminate the program if:
		-the output file already exists
		-the output file is invalid or can't be opened
*/
void collect_data()
{
	//##launch benchmark##
	int *pids = (int *)malloc(sizeof(int)*options_opt.num_processes);

	//0 = not exited. 1 = exited.
	int *pid_exited = (int *)malloc(sizeof(int)*options_opt.num_processes);
	int k;
	for(k = 0; k < options_opt.num_processes; k++)
	{
		int pid = launch_command(options_opt.cmd);
		pid_exited[k] = 0;
		pids[k] = pid;
	}

	completed_ms = 0;

	//open file descriptors
	int freq_fds[num_cores];
	char freq_buf[70];
	for(k = 0; k < num_cores; k++) {
		snprintf(freq_buf, sizeof(freq_buf),
			"/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq",
			k);
		freq_fds[k] = open(freq_buf, O_RDONLY);
		if(freq_fds[k] < 0) {
			die("Opening cpu frequency failed. %s\n", strerror(errno));
		}
	}
	
	//controller
	control_info_t control_data;
	

	//##output data##
	const struct timespec delay = {INTERVAL/1000,(INTERVAL%1000)*10e6};
	int sent_kill = 0;
	while(!done)
	{
		if(options_opt.timeout && completed_ms>timeout_ms && !sent_kill)
		{
			for(k = 0; k < options_opt.num_processes; k++)
			{
						kill_command(pids[k]);	
			}

			/*The purpose of marking sent_kill is to avoid sending kill signals twice.
			It's possible that the signal is sent, but that the process does not
			terminate immediately. Therefore, the data collection loop may occur one or more
			time subsequently; in these situations we do not want to resend the kill signal
			or collect new data. Initially, I did not have this variable, and I actually
			encountered this bug.*/
			sent_kill = 1;
		}

		done = 1;
		for(k = 0; k < options_opt.num_processes; k++)
		{
			if(!pid_exited[k])
				if(waitpid(pids[k], 0, WNOHANG))			
					pid_exited[k] = 1;
		}
		for(k = 0; k < options_opt.num_processes; k++)
		{
			if(!pid_exited[k])
			{
				done = 0;
				break;
			}
		}

		if(!sent_kill)
		{
			//temperatures
			int i;
			for(i = 0; i < num_cores; i++)
			{
				double t;
				int temp_status = temp_read(i, &t);
				if(temp_status != 0)
				{
					die("error %d: reading core %d T",
		        	   temp_status, i);
				}
				fprintf(output_file_handle, "%-15.1f", t);
				control_data.ts[i] = t;
			}


			//power
			control_data.pcpu = 0;
	  		for(i = 0; i < NUM_PWR_CHANNELS; i++) {
	  		  fprintf(output_file_handle, "%-15.8f ", curr_pwr[i]);
			  control_data.pcpu += curr_pwr[i]*MV_TO_CPU_POWER;
	  		}

			//fan speeds
			double fspeed;
			for(i = 0; i < NUM_FANS; i++)
			{
				fan_read(i,&fspeed);
				fprintf(output_file_handle, "%-15.5f", fspeed);
			}


			//power supplies. If we are not collecting data from
			//the power supplies, the globals are initialized to zero
			//and we will read these values.
			control_data.ptec = 0;
			for(i = 0; i < NUM_PWS_CHANNELS; i++)
			{
				fprintf(output_file_handle, "%-15.5f", curr_pws_v[i]);
				fprintf(output_file_handle, "%-15.5f", curr_pws_i[i]);
				control_data.ptec += curr_pws_v[i]*curr_pws_i[i];
			}
			
			//timestamp [ms]
			fprintf(output_file_handle, "%-15d", (int)completed_ms);

			//frequencies [khz]
			for(i = 0; i < num_cores; i++) {
				if(lseek(freq_fds[i],0,SEEK_SET) < 0)
					die("Seeking cpu freq. %s\n", strerror(errno));
				int bytesread = read(freq_fds[i], freq_buf, sizeof(freq_buf));
				if(bytesread < 0) {
					die("Reading cpu frequency failed. %s\n", strerror(errno));
				}
				//-1 to remove newline. TODO robust newline stripping
				freq_buf[bytesread-1] = 0; 
				fprintf(output_file_handle, "%-15.2f", atoi(freq_buf)/1000000.0);
			}
			fprintf(output_file_handle, "\n");

			//control
			#ifdef CONTROL_ENABLE
			if(completed_ms % (options_opt.control_params.interval*INTERVAL) == 0) {
				control_simple(control_data);
			}
			#endif

		}

		//nanosleep can be interrupted by signals, but
		//this case doesn't need to be handled in any special way.
		//If the child terminates, done will be set and data
		//collection will finish.
		nanosleep(&delay, NULL);
		completed_ms += INTERVAL;
	}
	
	for(k = 0; k < num_cores; k++) {
		if(close(freq_fds[k]) < 0)
			die("Could not close cpu freq fds %s\n", strerror(errno));
	}
	free(pids);
	free(pid_exited);
}