diff --git a/checkin_notes b/checkin_notes index 3a9f1d8291..5827a11d07 100755 --- a/checkin_notes +++ b/checkin_notes @@ -4546,3 +4546,24 @@ Karl 2003/05/06 sched/Makefile.in sched_fcgi/Makefile.in tools/Makefile.in + +Eric June 6, 2003 + - Removed old extraneous functions from wingui + (EnumWindowsProc, GetWndFromProcId) + - Moved GetByteString to util.C, made platform independent, + added "x/y KB" option + - Changed est_time_to_completion to use a recent exponential + average of change in percent done. This is more accurate + than the old method. + - Bug fixes involving result state changes + + client/ + app.C,h + client_types.h + client_state.C + win/ + wingui.cpp, h + wingui_mainwindow.cpp + wingui_piectrl.cpp + lib/ + util.C,h diff --git a/client/app.C b/client/app.C index e2fa4b8331..db53f7e4b4 100644 --- a/client/app.C +++ b/client/app.C @@ -59,6 +59,7 @@ #include #include #include +#include #include #include "client_state.h" @@ -928,6 +929,7 @@ int ACTIVE_TASK::get_cpu_time_via_os() { // int ACTIVE_TASK::get_cpu_time_via_shmem(time_t now) { char msg_buf[SHM_SEG_SIZE]; + double x; if (app_client_shm.get_msg(msg_buf, APP_CORE_WORKER_SEG)) { last_status_msg_time = now; fraction_done = current_cpu_time = checkpoint_cpu_time = 0.0; @@ -935,6 +937,18 @@ int ACTIVE_TASK::get_cpu_time_via_shmem(time_t now) { parse_double(msg_buf, "", current_cpu_time); parse_double(msg_buf, "", checkpoint_cpu_time); parse_double(msg_buf, "", working_set_size); + + recent_change += (fraction_done - last_frac_done); + if (last_frac_update==0) last_frac_update = now; + if ((now-last_frac_update)>0) { + x = exp(-(now-last_frac_update)*log(2.0)/20.0); + frac_rate_of_change *= x; + frac_rate_of_change += recent_change*(1-x); + last_frac_update = now; + recent_change = 0; + last_frac_done = fraction_done; + } + return 0; } @@ -966,7 +980,8 @@ double ACTIVE_TASK::est_time_to_completion() { if (fraction_done <= 0 || fraction_done > 1) { return -1; } - return (current_cpu_time / fraction_done) - current_cpu_time; + return (1.0-fraction_done)/frac_rate_of_change; + //return (current_cpu_time / fraction_done) - current_cpu_time; } // size of output files and files in slot dir diff --git a/client/app.h b/client/app.h index 1e34207916..3f093aaf79 100644 --- a/client/app.h +++ b/client/app.h @@ -71,6 +71,11 @@ public: // App's estimate of how much of the work unit is done. // Passed from the application via an API call; // will be zero if the app doesn't use this call + double frac_rate_of_change; + // How much the percent done changes per second, based + // on a recent exponential weighted average + double last_frac_done, recent_change; + time_t last_frac_update; double starting_cpu_time; // total CPU time at the start of current episode double checkpoint_cpu_time; @@ -78,7 +83,7 @@ public: double current_cpu_time; // most recent total CPU time reported by app double working_set_size; - // most recent size of RAM working set in bytes + // most recent size of RAM working set in bytes int current_disk_usage(double&); // disk used by output files and temp files of this task char slot_dir[256]; // directory where process runs @@ -138,7 +143,7 @@ public: void kill_tasks(); void get_cpu_times(); bool check_app_exited(); - bool check_rsc_limits_exceeded(); + bool check_rsc_limits_exceeded(); int get_free_slot(int total_slots); // screensaver-related functions diff --git a/client/client_types.h b/client/client_types.h index e0ee29d992..44e5dfe99b 100644 --- a/client/client_types.h +++ b/client/client_types.h @@ -201,12 +201,15 @@ struct WORKUNIT { bool had_failure(int& failnum); }; +// Keep the numbers in order based on chronological order +// A change to the numbers can cause results to be viewed as +// errors by the server #define RESULT_NEW 0 // New result, files may still need to be downloaded -#define RESULT_FILES_DOWNLOADED 1 // Files are downloaded, result can be computed -#define RESULT_COMPUTE_DONE 2 // Computation is done, if no error then files need to be uploaded -#define RESULT_FILES_UPLOADED 3 // Files are uploaded, notify scheduling server -#define RESULT_FILES_DOWNLOADING 4 // Files are being downloaded -#define RESULT_FILES_UPLOADING 5 // Files are being uploaded +#define RESULT_FILES_DOWNLOADING 1 // Files are being downloaded +#define RESULT_FILES_DOWNLOADED 2 // Files are downloaded, result can be computed +#define RESULT_COMPUTE_DONE 3 // Computation is done, if no error then files need to be uploaded +#define RESULT_FILES_UPLOADING 4 // Files are being uploaded +#define RESULT_FILES_UPLOADED 5 // Files are uploaded, notify scheduling server struct RESULT { char name[256]; diff --git a/client/win/wingui.cpp b/client/win/wingui.cpp index 7b6b47c2b2..382fd32eb2 100755 --- a/client/win/wingui.cpp +++ b/client/win/wingui.cpp @@ -26,7 +26,6 @@ void show_message(PROJECT* p, char* msg, int priority) { char* x; char message[1024]; - strcpy(message, msg); if (message[strlen(message)-1] == '\n') { message[strlen(message)-1] = 0; @@ -48,24 +47,6 @@ int add_new_project() { return 0; } -void GetByteString(double nbytes, CString* str) { - double xTera = (1024.0*1024*1024*1024); - double xGiga = (1024.0*1024*1024); - double xMega = (1024.0*1024); - double xKilo = (1024.0); - if (nbytes >= xTera) { - str->Format("%0.2f TB", nbytes/xTera); - } else if (nbytes >= xGiga) { - str->Format("%0.2f GB", nbytes/xGiga); - } else if (nbytes >= xMega) { - str->Format("%0.2f MB", nbytes/xMega); - } else if (nbytes >= xKilo) { - str->Format("%0.2f KB", nbytes/xKilo); - } else { - str->Format("%0.0f bytes", nbytes); - } -} - BOOL RequestNetConnect() { if(g_myWnd) { @@ -73,23 +54,3 @@ BOOL RequestNetConnect() } return FALSE; } - -BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) -{ - DWORD* dwInfo = (DWORD*)lParam; - DWORD dwFoundId; - GetWindowThreadProcessId(hwnd, &dwFoundId); - if(dwFoundId == dwInfo[0]) { - dwInfo[1] = (DWORD)CWnd::FromHandle(hwnd); - return FALSE; - } - dwInfo[1] = NULL; - return TRUE; -} - -CWnd* GetWndFromProcId(DWORD dwId) -{ - DWORD dwInfo[2] = {dwId, NULL}; - EnumWindows(EnumWindowsProc, (LPARAM)dwInfo); - return (CWnd*)dwInfo[1]; -} diff --git a/client/win/wingui.h b/client/win/wingui.h index b09b56ca63..23f32adcde 100755 --- a/client/win/wingui.h +++ b/client/win/wingui.h @@ -42,9 +42,6 @@ // functions int add_new_project(); -void GetByteString(double nbytes, CString* str); BOOL RequestNetConnect(); -BOOL CALLBACK EnumWindowsProc(HWND, LPARAM); -CWnd* GetWndFromProcId(DWORD); #endif diff --git a/client/win/wingui_mainwindow.cpp b/client/win/wingui_mainwindow.cpp index 509defede1..4dbdb2d360 100755 --- a/client/win/wingui_mainwindow.cpp +++ b/client/win/wingui_mainwindow.cpp @@ -396,9 +396,10 @@ void CMainWindow::UpdateGUI(CLIENT_STATE* pcs) m_XferListCtrl.SetItemProgress(i, 2, 100 * xSent / pfx->fip->nbytes); // size - strBuf.Format("%0.0f/%0.0fKB", xSent / 1024, pfx->fip->nbytes / 1024); - if (m_XferListCtrl.GetItemText(i, 3) != strBuf.GetBuffer(0)) - m_XferListCtrl.SetItemText(i, 3, strBuf.GetBuffer(0)); + char size_buf[256]; + get_byte_string(xSent, pfx->fip->nbytes, size_buf, 256); + if (strcmp(m_XferListCtrl.GetItemText(i, 3).GetBuffer(0), size_buf)) + m_XferListCtrl.SetItemText(i, 3, size_buf); // time double xtime = 0; diff --git a/client/win/wingui_piectrl.cpp b/client/win/wingui_piectrl.cpp index b7a8c7db36..1cafa905f8 100755 --- a/client/win/wingui_piectrl.cpp +++ b/client/win/wingui_piectrl.cpp @@ -335,10 +335,10 @@ void CPieChartCtrl::OnPaint() MemDC.LineTo(textrect.left, textrect.bottom); MemDC.LineTo(textrect.left, textrect.top); textrect.SetRect(PIE_BUFFER + 16, PIE_BUFFER + i * 20, wndrect.Width() - PIE_BUFFER, PIE_BUFFER + 20 + i * 20); - CString strBytes; - GetByteString(m_xValues.GetAt(i), &strBytes); + char size_buf[256]; + get_byte_string(m_xValues.GetAt(i), 0, size_buf, 256); CString strBuf; - strBuf.Format("%s (%s)", m_strLabels.GetAt(i).GetBuffer(0), strBytes.GetBuffer(0)); + strBuf.Format("%s (%s)", m_strLabels.GetAt(i).GetBuffer(0), size_buf); MemDC.DrawText(strBuf, textrect, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_END_ELLIPSIS); } diff --git a/lib/util.C b/lib/util.C index ac2eb25188..9facf0fce7 100755 --- a/lib/util.C +++ b/lib/util.C @@ -103,6 +103,44 @@ int double_to_ydhms (double x, int smallest_timescale, char *buf) { return 0; } +// Convert nbytes into a string. If total_bytes is non-zero, +// convert the two into a fractional display (i.e. 4/16 KB) +// +void get_byte_string(double nbytes, double total_bytes, char* str, int len) { + char buf[256]; + double xTera = (1024.0*1024.0*1024.0*1024.0); + double xGiga = (1024.0*1024.0*1024.0); + double xMega = (1024.0*1024.0); + double xKilo = (1024.0); + + if (total_bytes != 0) { + if (total_bytes >= xTera) { + sprintf(buf, "%0.2f/%0.2f TB", nbytes/xTera, total_bytes/xTera); + } else if (total_bytes >= xGiga) { + sprintf(buf, "%0.2f/%0.2f GB", nbytes/xGiga, total_bytes/xGiga); + } else if (total_bytes >= xMega) { + sprintf(buf, "%0.2f/%0.2f MB", nbytes/xMega, total_bytes/xMega); + } else if (total_bytes >= xKilo) { + sprintf(buf, "%0.2f/%0.2f KB", nbytes/xKilo, total_bytes/xKilo); + } else { + sprintf(buf, "%0.0f/%0.0f bytes", nbytes, total_bytes); + } + } else { + if (nbytes >= xTera) { + sprintf(buf, "%0.2f TB", nbytes/xTera); + } else if (nbytes >= xGiga) { + sprintf(buf, "%0.2f GB", nbytes/xGiga); + } else if (nbytes >= xMega) { + sprintf(buf, "%0.2f MB", nbytes/xMega); + } else if (nbytes >= xKilo) { + sprintf(buf, "%0.2f KB", nbytes/xKilo); + } else { + sprintf(buf, "%0.0f bytes", nbytes); + } + } + + safe_strncpy(str, buf, len); +} // return time of day as a double // Not necessarily in terms of UNIX time (especially on Windows) diff --git a/lib/util.h b/lib/util.h index ba0ebff16c..cbc0579921 100755 --- a/lib/util.h +++ b/lib/util.h @@ -20,6 +20,7 @@ #include extern int double_to_ydhms (double x, int smallest_timescale, char *buf); +extern void get_byte_string(double nbytes, double total_bytes, char* str, int len); extern double dtime(); extern void boinc_sleep(double); extern int parse_command_line( char *, char ** ); diff --git a/todo b/todo index f078a0799c..96148433c1 100755 --- a/todo +++ b/todo @@ -56,9 +56,6 @@ Windows screensaver functionality MEDIUM-PRIORITY (should do before public release) ----------------------- -more accurate time to completion calculation - - perhaps use recent change in percent done? - add an RPC to verify an account ID (returns DB ID for user) needed for multi-project stats sites