Esempio n. 1
0
gint profile(double* time_usr, double* time_sys, double* memory, double* correctness, gint suiteSize, gint isStd){
	double tusr=0, tsys=0, correctness_t=0;
	double stdTime=0;
	gint stdMemory=0;
	gint memory_new_one=0;
	double memory_new=0;
	allRequestPeak=0;
	noe=0;
	gchar* line;
	gchar* filename=g_malloc(128*sizeof(gchar));
	gchar* append=g_malloc(8*sizeof(gchar));
	if(isStd) g_snprintf(append, 32, ".s");
	else append[0]='\0';
	gint i, j, k, length=g_list_length(testcases);
	//gint fullTest=1;
	gint* testSuite=g_malloc0(length*sizeof(gint));
	double* testResults=g_malloc0(length*sizeof(double));
	gint* testMemory=g_malloc0(length*sizeof(gint));
	gint flippedSize, index;
	FILE* resultsFile;

	if(isStd>0 || suiteSize<=0 || suiteSize>length){
		suiteSize=length;
		for(i=0; i<suiteSize; i++){
			testSuite[i]=1;
		}
	}
	else{		// randomly sample testcases
		if(suiteSize>length/2){
			flippedSize=length-suiteSize;
		}
		else{
			flippedSize=suiteSize;
		}
		index=0;
		for(i=0; i<flippedSize; i++){
			j=g_rand_int_range(randomUtility, 1, length+1-i);
			while(j>0){
				index++;
				if(index>=length){
					index-=length;
				}
				if(testSuite[index]==0){
					j--;
				}
			}
			testSuite[index]=1;
		}
		if(flippedSize!=suiteSize){
			for(i=0; i<length; i++){
				testSuite[i]=1-testSuite[i];
			}
		}
	}
	// read testResults file
	if(!isStd){
		g_snprintf(filename, 128, "%stestResults.txt", CURRDIR);
		resultsFile=fopen(filename, "r");
		for(i=0; i<length; i++){
			fgets(filename, 128, resultsFile);
			sscanf(filename, "%lf\t%d", &testResults[i], &testMemory[i]);
			if(testSuite[i]){
				stdTime+=testResults[i];
				stdMemory+=testMemory[i];
			}
		}
		fclose(resultsFile);
	}
	// clean the output files
	for(i=0; i<length; i++){
		g_snprintf(filename, 128, "%sout%d%s", CURRDIR, i, append);
		if(g_file_test(filename, G_FILE_TEST_EXISTS)){
			g_remove(filename);
		}
	}
	line=g_malloc(512*sizeof(gchar));
	gchar **cmdv=NULL;
	gint pid, mpid;
	FILE *mfp;
	tusr=0;
	tsys=0;
	double tmp_double;
	gint tmp_int, timeout=1;
	struct rusage usage;
	struct timespec sleepUnit;
	sleepUnit.tv_sec=0;
	sleepUnit.tv_nsec=SLEEP_UNIT*1000;
	gint stdEvalTimes;
	if(isStd){
		stdEvalTimes=STD_EVALUATION_TIMES;
	}
	else{
		stdEvalTimes=1;
	}
	for(k=0; k<stdEvalTimes; k++){
		for(i=0; i<length; i++){
			if(testSuite[i]==0){
				continue;
			}
			j=i;
			g_snprintf(filename, 128, "%sout%d%s", CURRDIR, j, append);
			g_snprintf(line, 512, "subject %s%s", TESTCASEDIR, (char*)g_list_nth_data(testcases, j));
			g_shell_parse_argv(line, NULL, &cmdv, NULL);
			if((pid=fork())<0){
				g_printf("fork() for subject execution failed.\n");
				exit(0);
			}
			if(pid==0){
				if(g_freopen(filename, "w", stdout)==NULL) perror("redirect to file failed.");
				g_snprintf(filename, 128, "%sprocMemory%d", CURRDIR, j);
				if(g_freopen(filename, "w", stderr)==NULL) perror("redirect stderr to file failed.");
				execv("subject", cmdv);
				fprintf(logfp, "execv() failed.\n");
				fflush(logfp);
				exit(0);
			}
			g_strfreev(cmdv);

			// parent process, wait for pid
			if(isStd){
				wait4(pid, &tmp_int, 0, &usage);
			}
			else{
				timeout=(gint)(timeout_sec*1000000/SLEEP_UNIT);
				while(timeout>0 && wait4(pid, &tmp_int, WNOHANG, &usage)==0){
					timeout--;
					nanosleep(&sleepUnit, NULL);
				}
				if(timeout<=0){
					kill(pid, SIGKILL);
					waitpid(pid, &tmp_int, 0);
					break;
				}
			}
#ifdef CUSTOM_EXTRA_SAVING
			CUSTOM_EXTRA_SAVING;
#endif
			//g_spawn_close_pid(pid);
			memory_new_one=readProcMemory(j);
			if(isStd && k==0){
				testMemory[i]=memory_new_one;
			}
			memory_new+=memory_new_one;
			tmp_double=usage.ru_utime.tv_sec+(usage.ru_utime.tv_usec)/(double)1000000;
			if(isStd){
				testResults[i]+=tmp_double;
			}
			tusr+=tmp_double;
			tmp_double=usage.ru_stime.tv_sec+(usage.ru_stime.tv_usec)/(double)1000000;
			if(isStd){
				testResults[i]+=tmp_double;
			}
			tsys+=tmp_double;
			// when the total execution time exceeds time limit, directly return
			if(isStd==0){
				g_snprintf(filename, 128, "%sout%d", CURRDIR, j);
				g_snprintf(line, 128, "%sout%d.s", CURRDIR, j);
				if(cmpOutput(filename, line) || tusr+tsys>timeout_sec){
					timeout=-1;
					break;
				}
			}
		}
	}
	// cmp the output and summarise the correctness
	if(timeout<=0){
		correctness_t=i+1;
	}
	else{
		tusr/=stdEvalTimes;
		tsys/=stdEvalTimes;
		memory_new/=stdEvalTimes;
		if(isStd==0){
#ifdef CUSTOM_CORRECTNESS
			CUSTOM_CORRECTNESS;
#else
			for(i=0; i<length; i++){
				if(testSuite[i]==0){
					continue;
				}
				g_snprintf(filename, 128, "%sout%d", CURRDIR, i);
				g_snprintf(line, 128, "%sout%d.s", CURRDIR, i);
				correctness_t+=cmpOutput(filename, line);
			}
#endif
			tusr/=stdTime;
			tsys/=stdTime;
			memory_new/=stdMemory;
		}
		else{
			g_snprintf(filename, 128, "%stestResults.txt", CURRDIR);
			resultsFile=fopen(filename, "w+");
			for(i=0; i<length; i++){
				g_fprintf(resultsFile, "%lf\t%d\n", testResults[i]/stdEvalTimes, testMemory[i]);
			}
			fclose(resultsFile);
			memory_new/=1024;
		}
	}
	g_free(filename);
	g_free(append);
	g_snprintf(line, 128, "%lf %lf %lf %lf\n", tusr, tsys, memory_new, correctness_t);
	gint lineLength=strlen(line);
	write(STDOUT_FILENO, line, lineLength);
	//g_printf("%d\n", allRequestPeak/stdEvalTimes);
	g_free(line);
	g_free(testSuite);
	g_free(testResults);
	g_free(testMemory);
	*time_usr=tusr;
	*time_sys=tsys;
	*memory=memory_new/(double)1024;
	*correctness=correctness_t;
	return 0;
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
#ifdef _WIN32
  // on Windows we have a hard time showing stuff printed to stdout/stderr to the user.
  // because of that we write it to a log file.
  char datetime[20];
  dt_gettime(datetime, sizeof(datetime));

  // make sure to not redirect output when the output is already being redirected, either to a file or a pipe.
  int out_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
  int err_type = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
  gboolean redirect_output = ((out_type != FILE_TYPE_DISK && out_type != FILE_TYPE_PIPE) &&
                              (err_type != FILE_TYPE_DISK && err_type != FILE_TYPE_PIPE));

  for(int k = 1; k < argc; k++)
  {
    // For simple arguments do not redirect stdout
    if(!strcmp(argv[k], "--help") || !strcmp(argv[k], "-h") || !strcmp(argv[k], "/?") || !strcmp(argv[k], "--version"))
    {
      redirect_output = FALSE;
      break;
    }
  }

  if(redirect_output)
  {
    // something like C:\Users\username\AppData\Local\Microsoft\Windows\Temporary Internet Files\darktable\darktable-log.txt
    char *logdir = g_build_filename(g_get_user_cache_dir(), "darktable", NULL);
    char *logfile = g_build_filename(logdir, "darktable-log.txt", NULL);

    g_mkdir_with_parents(logdir, 0700);

    g_freopen(logfile, "a", stdout);
    dup2(fileno(stdout), fileno(stderr));

    // We don't need the console window anymore, free it
    // This ensures that only darktable's main window will be visible
    FreeConsole();

    g_free(logdir);
    g_free(logfile);

    // don't buffer stdout/stderr. we have basically two options: unbuffered or line buffered.
    // unbuffered keeps the order in which things are printed but concurrent threads printing can lead to intermangled output. ugly.
    // line buffered should keep lines together but in my tests the order of things no longer matches. ugly and potentially confusing.
    // thus we are doing the thing that is just ugly (in rare cases) but at least not confusing.
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    printf("========================================\n");
    printf("version: %s\n", darktable_package_string);
    printf("start: %s\n", datetime);
    printf("\n");
  }
#endif

  if(dt_init(argc, argv, TRUE, TRUE, NULL)) exit(1);
  dt_gui_gtk_run(darktable.gui);

#ifdef _WIN32
  if(redirect_output)
  {
    dt_gettime(datetime, sizeof(datetime));
    printf("\n");
    printf("end:   %s\n", datetime);
    printf("========================================\n");
    printf("\n");
  }
#endif

  exit(0);
}