int main ( int argc, char *argv[]) { char buf[256]; int named_ini_files = -1; int contact_server = 0; int torture_test = 0; int i, nice_level; char *p; /* catch termination signals */ (void)signal(SIGTERM, sigterm_handler); (void)signal(SIGINT, sigterm_handler); /* No buffering of output */ setvbuf (stdout, NULL, _IONBF, 0); /* Change to the executable's directory */ /* NOTE: This only changes the working directory if the user typed */ /* in a full path to the executable (as opposed to finding it on the PATH) */ strcpy (buf, argv[0]); p = strrchr (buf, '/'); if (p != NULL) { *p = 0; (void) _chdir (buf); } /* Initialize gwnum call back routines. Using callback routines lets the */ /* gwnum library have a nice clean interface for users that do not need */ /* additional functionality that only prime95 uses. */ StopCheckRoutine = stopCheck; OutputBothRoutine = OutputBoth; /* Process command line switches */ for (i = 1; i < argc; i++) { p = argv[i]; if (*p++ != '-') break; switch (*p++) { /* Accept a -A switch indicating an alternate set of INI files */ /* are to be used. */ case 'A': case 'a': named_ini_files = 0; while (isspace (*p)) p++; while (isdigit (*p)) { named_ini_files = named_ini_files * 10 + (*p - '0'); p++; } break; /* -C - contact the server now, then exit */ case 'C': case 'c': contact_server = 1; VERBOSE = TRUE; NO_GUI = FALSE; break; /* -D - debug */ case 'D': case 'd': VERBOSE = TRUE; NO_GUI = FALSE; break; /* -H - help */ case 'H': case 'h': case '?': goto usage; /* -M - Menu */ case 'M': case 'm': MENUING = 1; NO_GUI = FALSE; break; /* -S - status */ case 'S': case 's': MENUING = 2; NO_GUI = FALSE; break; /* -T - Torture test */ case 'T': case 't': torture_test = TRUE; break; /* -V - version number */ case 'V': case 'v': printf ("Mersenne Prime Test Program, Version %s.%d\n", VERSION, PORT); return (0); /* -W - use a different working directory */ case 'W': case 'w': (void) _chdir (p); break; /* Otherwise unknown switch */ default: printf ("Invalid switch\n"); goto usage; } } /* Determine the names of the INI files, read them, do other initialization. */ /* Skip the comm code initialization if we are just displaying the status */ /* or running a torture test */ nameAndReadIniFiles (named_ini_files); if (MENUING != 2 && !torture_test) initCommCode (); /* If not running a torture test, set the program to nice priority. */ /* Technically, this is not necessary since worker threads are set to */ /* the lowest possible priority. However, sysadmins might be alarmed */ /* to see a CPU intensive program not running at nice priority when */ /* executing a ps command. */ #if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD__) /* Linux/FreeBSD ranges from -20 to +19, lower values give more favorable scheduling */ nice_level = IniGetInt (INI_FILE, "Nice", 10); if (!torture_test && nice_level) { setpriority (PRIO_PROCESS, 0, nice_level); } #endif /* If running the torture test, do so now. */ if (torture_test) { int num_threads; VERBOSE = TRUE; NO_GUI = FALSE; num_threads = IniGetInt (INI_FILE, "TortureThreads", NUM_CPUS * CPU_HYPERTHREADS); LaunchTortureTest (num_threads, TRUE); } /* If this is a stress tester, then turn on menuing. */ else if (IniGetInt (INI_FILE, "StressTester", 99) == 1) { MENUING = 1; VERBOSE = TRUE; NO_GUI = FALSE; main_menu (); } /* On first run, get user id before contacting server */ /* for a work assignment. To make first time user more comfortable, we will */ /* display data to the screen, rather than running silently. */ else if (IniGetInt (INI_FILE, "StressTester", 99) == 99) { VERBOSE = TRUE; NO_GUI = FALSE; test_welcome (); } /* If we are to contact the server, do so now. This option lets the */ /* user create a batch file that contacts the server at regular intervals */ /* or when the ISP is contacted, etc. */ else if (contact_server) { do_manual_comm_now (); while (COMMUNICATION_THREAD) Sleep (50); } /* Bring up the main menu */ else if (MENUING == 1) main_menu (); else if (MENUING == 2) test_status(); /* Continue testing, return when worker threads exit. */ else { linuxContinue ("Another mprime is already running!\n", ALL_WORKERS, TRUE); } /* Write the worktodo file in case the WELL_BEHAVED_WORK flag caused us */ /* to delay writing the file. */ writeWorkToDoFile (TRUE); /* All done */ return (0); /* Invalid args message */ usage: printf ("Usage: mprime [-cdhmstv] [-aN] [-wDIR]\n"); printf ("-c\tContact the PrimeNet server, then exit.\n"); printf ("-d\tPrint detailed information to stdout.\n"); printf ("-h\tPrint this.\n"); printf ("-m\tMenu to configure mprime.\n"); printf ("-s\tDisplay status.\n"); printf ("-t\tRun the torture test.\n"); printf ("-v\tPrint the version number.\n"); printf ("-aN\tUse an alternate set of INI and output files (obsolete).\n"); printf ("-wDIR\tRun from a different working directory.\n"); printf ("\n"); return (1); }
void torture (void) { unsigned long m_thread, m_type, m_minfft, m_maxfft; unsigned long m_memory, m_timefft; unsigned long mem, blendmemory; m_thread = NUM_CPUS * CPU_HYPERTHREADS; mem = physical_memory (); if (mem >= 2000) { blendmemory = GetSuggestedMemory (1600); } else if (mem >= 500) { blendmemory = GetSuggestedMemory (mem - 256); } else if (mem >= 200) { blendmemory = GetSuggestedMemory (mem / 2); } else { blendmemory = 8; } m_timefft = 3; if (NUM_CPUS * CPU_HYPERTHREADS > 1) askNum ("Number of torture test threads to run", &m_thread, 1, NUM_CPUS * CPU_HYPERTHREADS); outputLongLine ("Choose a type of torture test to run.\n 1 = Small FFTs (maximum heat and FPU stress, data fits in L2 cache, RAM not tested much).\n 2 = In-place large FFTs (maximum power consumption, some RAM tested).\n 3 = Blend (tests some of everything, lots of RAM tested).\n 11,12,13 = Allows you to fine tune the above three selections.\nBlend is the default. NOTE: if you fail the blend test, but can pass the small FFT test then your problem is likely bad memory or a bad memory controller.\n"); m_type = 3; askNum ("Type of torture test to run", &m_type, 1, 13); if (m_type == 1 || m_type == 11) { m_minfft = 8; m_maxfft = 64; m_memory = 0; } else if (m_type == 2 || m_type == 12) { m_minfft = 128; m_maxfft = 1024; m_memory = 0; } else { m_minfft = 8; m_maxfft = 4096; m_memory = blendmemory; } if (m_type >= 11) { askNum ("Min FFT size (in K)", &m_minfft, (CPU_FLAGS & CPU_AVX) ? 0 : 7, (CPU_FLAGS & CPU_SSE2 ? MAX_FFTLEN_SSE2 : MAX_FFTLEN) / 1024); askNum ("Max FFT size (in K)", &m_maxfft, (CPU_FLAGS & CPU_AVX) ? 1 : 7, (CPU_FLAGS & CPU_SSE2 ? MAX_FFTLEN_SSE2 : MAX_FFTLEN) / 1024); if (blendmemory > 8) askNum ("Memory to use (in MB, 0 = in-place FFTs)", &m_memory, 0, mem); askNum ("Time to run each FFT size (in minutes)", &m_timefft, 1, 60); } if (askOkCancel ()) { IniWriteInt (INI_FILE, "MinTortureFFT", m_minfft); IniWriteInt (INI_FILE, "MaxTortureFFT", m_maxfft); mem = m_memory / m_thread; IniWriteInt (INI_FILE, "TortureMem", mem); IniWriteInt (INI_FILE, "TortureTime", m_timefft); LaunchTortureTest (m_thread, TRUE); } }