mirror of https://github.com/BOINC/boinc.git
parent
7c2bf460e2
commit
f9f3aad4a8
|
@ -352,19 +352,24 @@ int boinc_child_done(double cpu) {
|
|||
}
|
||||
|
||||
double boinc_cpu_time() {
|
||||
double cpu_secs;
|
||||
|
||||
// Start with the CPU time from previous runs, then
|
||||
// add the CPU time of the current run
|
||||
cpu_secs = aid.wu_cpu_time;
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
int retval, pid = getpid();
|
||||
struct rusage ru;
|
||||
double cpu_secs;
|
||||
retval = getrusage(RUSAGE_SELF, &ru);
|
||||
if(retval) fprintf(stderr, "error: could not get cpu time for %d\n", pid);
|
||||
// Sum the user and system time spent in this process
|
||||
cpu_secs = (double)ru.ru_utime.tv_sec + (((double)ru.ru_utime.tv_usec) / ((double)1000000.0));
|
||||
cpu_secs += (double)ru.ru_utime.tv_sec + (((double)ru.ru_utime.tv_usec) / ((double)1000000.0));
|
||||
cpu_secs += (double)ru.ru_stime.tv_sec + (((double)ru.ru_stime.tv_usec) / ((double)1000000.0));
|
||||
return cpu_secs;
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#ifdef WINNT_CLOCK
|
||||
//#ifdef WINNT_CLOCK
|
||||
HANDLE hProcess;
|
||||
FILETIME creationTime,exitTime,kernelTime,userTime;
|
||||
|
||||
|
@ -382,27 +387,27 @@ double boinc_cpu_time() {
|
|||
tKernel.HighPart = kernelTime.dwHighDateTime;
|
||||
tUser.LowPart = userTime.dwLowDateTime;
|
||||
tUser.HighPart = userTime.dwHighDateTime;
|
||||
totTime = tKernel.QuadPart + tUser.QuadPart;
|
||||
|
||||
// Runtimes in 100-nanosecond units
|
||||
totTime = tKernel.QuadPart + tUser.QuadPart;
|
||||
cpu_secs += totTime / 10000000.0;
|
||||
|
||||
// Convert to seconds and return
|
||||
return(totTime / 10000000.0);
|
||||
return cpu_secs;
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
// ... fall through
|
||||
#endif // WINNT_CLOCK
|
||||
//#endif // WINNT_CLOCK
|
||||
// TODO: Handle timer wraparound
|
||||
static bool first=true;
|
||||
static DWORD last_count = 0;
|
||||
static DWORD first_count = 0;
|
||||
|
||||
if (first) {
|
||||
last_count = GetTickCount();
|
||||
first = true;
|
||||
first_count = GetTickCount();
|
||||
first = false;
|
||||
}
|
||||
DWORD cur = GetTickCount();
|
||||
double x = (cur - last_count)/1000.;
|
||||
last_count = cur;
|
||||
return x;
|
||||
return cpu_secs + ((cur - first_count)/1000.);
|
||||
#endif // _WIN32
|
||||
#endif
|
||||
|
||||
|
|
15
client/app.C
15
client/app.C
|
@ -247,6 +247,9 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
|
||||
fclose(f);
|
||||
|
||||
sprintf(temp, "%s%s%s", slot_dir, PATH_SEPARATOR, SUSPEND_QUIT_FILE);
|
||||
file_delete(temp);
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
char* argv[100];
|
||||
|
@ -406,14 +409,13 @@ bool ACTIVE_TASK_SET::poll() {
|
|||
// Runtimes in 100-nanosecond units
|
||||
totTime = tKernel.QuadPart + tUser.QuadPart;
|
||||
|
||||
atp->result->final_cpu_time = (totTime / 10000000.0);
|
||||
//atp->result->final_cpu_time = atp->starting_cpu_time + (totTime / 10000000.0);
|
||||
} else {
|
||||
// This probably isn't correct
|
||||
atp->result->final_cpu_time = ((double)clock())/CLOCKS_PER_SEC;
|
||||
//atp->result->final_cpu_time = atp->starting_cpu_time + ((double)clock())/CLOCKS_PER_SEC;
|
||||
}
|
||||
if (exit_code != STILL_ACTIVE) {
|
||||
found = true;
|
||||
// Not sure how to incorporate the other states (WAS_SIGNALED, etc)
|
||||
atp->state = PROCESS_EXITED;
|
||||
atp->exit_status = exit_code;
|
||||
atp->result->exit_status = atp->exit_status;
|
||||
|
@ -621,6 +623,13 @@ bool ACTIVE_TASK::check_app_status_files() {
|
|||
return found;
|
||||
}
|
||||
|
||||
// Returns the estimated time to completion (in seconds) of this
|
||||
// active task, based on current reported CPU time and fraction done
|
||||
//
|
||||
double ACTIVE_TASK::est_time_to_completion() {
|
||||
return (current_cpu_time / fraction_done) - current_cpu_time;
|
||||
}
|
||||
|
||||
// Poll each of the currently running tasks and get their CPU time
|
||||
//
|
||||
bool ACTIVE_TASK_SET::poll_time() {
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
void suspend(bool suspend);
|
||||
|
||||
bool check_app_status_files();
|
||||
double est_time_to_completion();
|
||||
|
||||
int write(FILE*);
|
||||
int parse(FILE*, CLIENT_STATE*);
|
||||
|
|
|
@ -38,21 +38,20 @@ int CLIENT_STATE::make_slot_dirs() {
|
|||
|
||||
// Perform a graceful shutdown of the client, including quitting
|
||||
// all applications, checking their final status, and writing
|
||||
// the client_state.xml file
|
||||
// the client_state.xml file (should we also terminate net_xfers here?)
|
||||
//
|
||||
int CLIENT_STATE::exit() {
|
||||
int retval;
|
||||
active_tasks.poll_time();
|
||||
retval = write_state_file();
|
||||
if (retval) {
|
||||
fprintf(stderr, "error: CLIENT_STATE.exit: write_state_file failed\n");
|
||||
return retval;
|
||||
}
|
||||
retval = exit_tasks();
|
||||
if (retval) {
|
||||
fprintf(stderr, "error: CLIENT_STATE.exit: exit_tasks failed\n");
|
||||
return retval;
|
||||
}
|
||||
retval = write_state_file();
|
||||
if (retval) {
|
||||
fprintf(stderr, "error: CLIENT_STATE.exit: write_state_file failed\n");
|
||||
return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ GLOBAL_PREFS::GLOBAL_PREFS() {
|
|||
disk_max_used_gb = 1;
|
||||
disk_max_used_pct = 0.5;
|
||||
disk_min_free_gb = 0.1;
|
||||
idle_time_to_run = 5;
|
||||
idle_time_to_run = 0;
|
||||
};
|
||||
|
||||
// Parse XML global prefs
|
||||
|
|
|
@ -1090,14 +1090,20 @@ void CMainWindow::UpdateGUI(CLIENT_STATE* cs)
|
|||
m_ResultListCtrl.SetItemText(i, 2, re->name);
|
||||
|
||||
// cpu time
|
||||
int cpuhour = (int)(re->final_cpu_time / (60 * 60));
|
||||
int cpumin = (int)(re->final_cpu_time / 60) % 60;
|
||||
int cpusec = (int)(re->final_cpu_time) % 60;
|
||||
ACTIVE_TASK* at = gstate.lookup_active_task_by_result(re);
|
||||
double cur_cpu;
|
||||
if (at) {
|
||||
cur_cpu = at->current_cpu_time;
|
||||
} else {
|
||||
cur_cpu = 0;
|
||||
}
|
||||
int cpuhour = (int)(cur_cpu / (60 * 60));
|
||||
int cpumin = (int)(cur_cpu / 60) % 60;
|
||||
int cpusec = (int)(cur_cpu) % 60;
|
||||
buf.Format("%0.2dh%0.2dm%0.2ds", cpuhour, cpumin, cpusec);
|
||||
m_ResultListCtrl.SetItemText(i, 3, buf);
|
||||
|
||||
// progress
|
||||
ACTIVE_TASK* at = gstate.lookup_active_task_by_result(re);
|
||||
if(!at) {
|
||||
m_ResultListCtrl.SetItemProgress(i, 4, 0);
|
||||
} else {
|
||||
|
@ -1108,7 +1114,7 @@ void CMainWindow::UpdateGUI(CLIENT_STATE* cs)
|
|||
if(!at || at->fraction_done == 0) {
|
||||
buf.Format("unable to calculate");
|
||||
} else {
|
||||
int tocomp = (re->final_cpu_time / at->fraction_done) - re->final_cpu_time;
|
||||
double tocomp = at->est_time_to_completion();
|
||||
cpuhour = (int)(tocomp / (60 * 60));
|
||||
cpumin = (int)(tocomp / 60) % 60;
|
||||
cpusec = (int)(tocomp) % 60;
|
||||
|
@ -1121,7 +1127,11 @@ void CMainWindow::UpdateGUI(CLIENT_STATE* cs)
|
|||
case RESULT_NEW:
|
||||
buf.Format("%s", "New"); break;
|
||||
case RESULT_FILES_DOWNLOADED:
|
||||
buf.Format("%s", "Ready to run"); break;
|
||||
if (at)
|
||||
buf.Format("%s", "Running");
|
||||
else
|
||||
buf.Format("%s", "Ready to run");
|
||||
break;
|
||||
case RESULT_COMPUTE_DONE:
|
||||
buf.Format("%s", "Computation done"); break;
|
||||
case RESULT_READY_TO_ACK:
|
||||
|
|
Loading…
Reference in New Issue