From 8a3e89f69845671a3ddf4067c9346335d450876f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 1 Apr 2003 03:28:37 +0000 Subject: [PATCH] random send order svn path=/trunk/boinc/; revision=1121 --- checkin_notes | 36 +++++++++++ client/app.C | 2 + client/client_state.C | 137 +++++++++++++++++++++------------------- client/client_state.h | 22 ++++--- client/file_names.h | 34 +++++----- client/hostinfo.C | 20 +++--- client/hostinfo.h | 4 +- client/pers_file_xfer.C | 23 +++++-- client/speed_stats.h | 20 +++--- db/constraints.sql | 2 +- db/db.h | 1 + db/db_mysql.C | 7 +- db/schema.sql | 1 + html/user/prefs.inc | 4 +- html/user/user.inc | 4 +- sched/make_work.C | 11 ++-- test/test_1sec.php | 2 +- test/test_backend.php | 2 +- test/test_uc.php | 4 +- todo | 9 +++ tools/backend_lib.C | 1 + 21 files changed, 209 insertions(+), 137 deletions(-) diff --git a/checkin_notes b/checkin_notes index d5ecd50725..0ad59023a2 100755 --- a/checkin_notes +++ b/checkin_notes @@ -3967,3 +3967,39 @@ David Mar 31 2003 team_create_action.php test/ test_uc.php + +David Mar 31 2003 + - added random field to result. + Results are sent in random order, making it hard for hackers + to get multiple results for the same WU + - user-visible messages about files give names, not URLs + - Changed all occurrences of "time test" and "speed test" + to "CPU benchmark". + Please use accurate, consistent terminology in the code. + - changed command-line options: + -skip_cpu_benchmarks instead of -no_time_tests + -run_cpu_benchmarks instead of -run_speed_test + + client/ + client_state.C,h + file_names.h + hostinfo.C,h + net_xfer.C + pers_file_xfer.C + speed_stats.h + db/ + constraints.sql + db.h + db_mysql.C + schema.sql + html_user/ + prefs.inc + user.inc + sched/ + make_work.C + test/ + test_1sec.php + test_backend.php + test_uc.php + tools/ + backend_lib.C diff --git a/client/app.C b/client/app.C index 6821bc86c7..503e347d97 100644 --- a/client/app.C +++ b/client/app.C @@ -437,6 +437,7 @@ int ACTIVE_TASK_SET::insert(ACTIVE_TASK* atp) { return 0; } +#if 0 void ACTIVE_TASK_SET::free_mem() { vector::iterator at_iter; ACTIVE_TASK *at; @@ -448,6 +449,7 @@ void ACTIVE_TASK_SET::free_mem() { delete at; } } +#endif // Checks if any child processes have exited and records their final CPU time // diff --git a/client/client_state.C b/client/client_state.C index 23ff7edb9b..e2305e7d2c 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -67,7 +67,8 @@ CLIENT_STATE::CLIENT_STATE() { client_state_dirty = false; exit_when_idle = false; update_prefs = false; - run_time_test = true; + run_cpu_benchmarks = false; + skip_cpu_benchmarks = false; file_xfer_giveup_period = PERS_GIVEUP; contacted_sched_server = false; activities_suspended = false; @@ -86,14 +87,16 @@ CLIENT_STATE::CLIENT_STATE() { strcpy(socks_user_passwd, ""); strcpy(host_venue, ""); suspend_requested = false; - run_speed_test = false; start_saver = false; #ifdef _WIN32 - time_tests_handle = NULL; + cpu_benchmarks_handle = NULL; #endif - time_tests_id = 0; + cpu_benchmarks_id = 0; } +#if 0 +// what's the purpose of this? + void CLIENT_STATE::free_mem() { vector::iterator proj_iter; vector::iterator app_iter; @@ -152,6 +155,7 @@ void CLIENT_STATE::free_mem() { active_tasks.free_mem(); } +#endif void CLIENT_STATE::install_global_prefs() { net_xfers->max_bytes_sec_up = global_prefs.max_bytes_sec_up; @@ -211,17 +215,17 @@ int CLIENT_STATE::init() { // running CPU benchmarks is slow, so do it infrequently // - if (gstate.should_run_time_tests()) { - time_tests_start = time(0); + if (gstate.should_run_cpu_benchmarks()) { + cpu_benchmarks_start = time(0); show_message(NULL, "Running CPU benchmarks", MSG_INFO); #ifdef _WIN32 - time_tests_handle = CreateThread( - NULL, 0, win_time_tests, NULL, 0, &time_tests_id + cpu_benchmarks_handle = CreateThread( + NULL, 0, win_cpu_benchmarks, NULL, 0, &cpu_benchmarks_id ); #else - time_tests_id = fork(); - if (time_tests_id == 0) { - _exit(time_tests()); + cpu_benchmarks_id = fork(); + if (cpu_benchmarks_id == 0) { + _exit(cpu_benchmarks()); } #endif } @@ -257,19 +261,19 @@ int CLIENT_STATE::init() { return 0; } -// Returns true if time tests should be run -// flag or if it's been a month since we last checked time stats +// Returns true if CPU benchmarks should be run: +// flag is set or it's been a month since we last ran // -bool CLIENT_STATE::should_run_time_tests() { +bool CLIENT_STATE::should_run_cpu_benchmarks() { return ( - run_speed_test || + run_cpu_benchmarks || (difftime(time(0), (time_t)host_info.p_calculated) > BENCHMARK_PERIOD) ); } #ifdef _WIN32 -DWORD WINAPI CLIENT_STATE::win_time_tests(LPVOID) { - return gstate.time_tests(); +DWORD WINAPI CLIENT_STATE::win_cpu_benchmarks(LPVOID) { + return gstate.cpu_benchmarks(); } #endif @@ -277,7 +281,7 @@ DWORD WINAPI CLIENT_STATE::win_time_tests(LPVOID) { // NOTE: this locks up the process for 10-20 seconds, // so it should be called very seldom // -int CLIENT_STATE::time_tests() { +int CLIENT_STATE::cpu_benchmarks() { HOST_INFO host_info; FILE* finfo; double fpop_test_secs = 3.3; @@ -286,9 +290,17 @@ int CLIENT_STATE::time_tests() { clear_host_info(host_info); if (log_flags.measurement_debug) { - printf("Running time tests.\n"); + printf("Running CPU benchmarks.\n"); } - if (run_time_test) { + if (skip_cpu_benchmarks) { + if (log_flags.measurement_debug) { + show_message(0, "Skipping CPU benchmarks\n", MSG_INFO); + } + host_info.p_fpops = 1e9; + host_info.p_iops = 1e9; + host_info.p_membw = 4e9; + host_info.m_cache = 1e6; + } else { if (log_flags.measurement_debug) { printf( "Running floating point test for about %.1f seconds.\n", @@ -315,85 +327,77 @@ int CLIENT_STATE::time_tests() { // need to check cache!! host_info.m_cache = 1e6; - } else { - if (log_flags.measurement_debug) { - printf("Using fake performance numbers\n"); - } - host_info.p_fpops = 1e9; - host_info.p_iops = 1e9; - host_info.p_membw = 4e9; - host_info.m_cache = 1e6; } host_info.p_calculated = (double)time(0); - finfo = fopen(TIME_TESTS_FILE_NAME, "w"); + finfo = fopen(CPU_BENCHMARKS_FILE_NAME, "w"); if(!finfo) return ERR_FOPEN; - host_info.write_time_tests(finfo); + host_info.write_cpu_benchmarks(finfo); fclose(finfo); return 0; } -// checks if the time tests are running +// checks if the CPU benchmarks are running // -int CLIENT_STATE::check_time_tests() { +int CLIENT_STATE::check_cpu_benchmarks() { FILE* finfo; int retval; - if (time_tests_id) { + if (cpu_benchmarks_id) { #ifdef _WIN32 DWORD exit_code = 0; - GetExitCodeThread(time_tests_handle, &exit_code); + GetExitCodeThread(cpu_benchmarks_handle, &exit_code); if(exit_code == STILL_ACTIVE) { - if(time(NULL) > time_tests_start + MAX_TIME_TESTS_SECONDS) { + if(time(NULL) > cpu_benchmarks_start + MAX_CPU_BENCHMARKS_SECONDS) { show_message(NULL, "CPU benchmarks timed out, using default values", MSG_ERROR); - TerminateThread(time_tests_handle, 0); - CloseHandle(time_tests_handle); + TerminateThread(cpu_benchmarks_handle, 0); + CloseHandle(cpu_benchmarks_handle); host_info.p_fpops = 1e9; host_info.p_iops = 1e9; host_info.p_membw = 4e9; host_info.m_cache = 1e6; - time_tests_id = 0; - return TIME_TESTS_ERROR; + cpu_benchmarks_id = 0; + return CPU_BENCHMARKS_ERROR; } - return TIME_TESTS_RUNNING; + return CPU_BENCHMARKS_RUNNING; } - CloseHandle(time_tests_handle); + CloseHandle(cpu_benchmarks_handle); #else int exit_code = 0; - retval = waitpid(time_tests_id, &exit_code, WNOHANG); + retval = waitpid(cpu_benchmarks_id, &exit_code, WNOHANG); if(retval == 0) { - if((unsigned int)time(NULL) > time_tests_start + MAX_TIME_TESTS_SECONDS) { + if((unsigned int)time(NULL) > cpu_benchmarks_start + MAX_CPU_BENCHMARKS_SECONDS) { show_message(NULL, "CPU benchmarks timed out, using default values", MSG_ERROR); - kill(time_tests_id, SIGKILL); + kill(cpu_benchmarks_id, SIGKILL); host_info.p_fpops = 1e9; host_info.p_iops = 1e9; host_info.p_membw = 4e9; host_info.m_cache = 1e6; - time_tests_id = 0; - return TIME_TESTS_ERROR; + cpu_benchmarks_id = 0; + return CPU_BENCHMARKS_ERROR; } - return TIME_TESTS_RUNNING; + return CPU_BENCHMARKS_RUNNING; } #endif - time_tests_id = 0; + cpu_benchmarks_id = 0; show_message(NULL, "CPU benchmarks complete", MSG_INFO); - finfo = fopen(TIME_TESTS_FILE_NAME, "r"); + finfo = fopen(CPU_BENCHMARKS_FILE_NAME, "r"); if (!finfo) { show_message(NULL, "Can't open CPU benchmark file, using default values", MSG_ERROR); host_info.p_fpops = 1e9; host_info.p_iops = 1e9; host_info.p_membw = 4e9; host_info.m_cache = 1e6; - return TIME_TESTS_ERROR; + return CPU_BENCHMARKS_ERROR; } - retval = host_info.parse_time_tests(finfo); + retval = host_info.parse_cpu_benchmarks(finfo); fclose(finfo); - if (retval) return TIME_TESTS_ERROR; - file_delete(TIME_TESTS_FILE_NAME); - return TIME_TESTS_COMPLETE; + if (retval) return CPU_BENCHMARKS_ERROR; + file_delete(CPU_BENCHMARKS_FILE_NAME); + return CPU_BENCHMARKS_COMPLETE; } - return TIME_TESTS_NOT_RUNNING; + return CPU_BENCHMARKS_NOT_RUNNING; } // Return the maximum allowed disk usage as determined by user preferences. @@ -471,11 +475,12 @@ int CLIENT_STATE::check_suspend_activities() { sprintf(susp_msg, "Suspending activity - time of day"); } } - // Stop the applications while we're running time tests + + // Don't work while we're running CPU benchmarks // - if (check_time_tests() == TIME_TESTS_RUNNING) { + if (check_cpu_benchmarks() == CPU_BENCHMARKS_RUNNING) { should_suspend = true; - sprintf(susp_msg, "Suspending activity - running time tests"); + sprintf(susp_msg, "Suspending activity - running CPU benchmarks"); } if (should_suspend) { @@ -520,7 +525,7 @@ bool CLIENT_STATE::do_something() { check_suspend_activities(); - if (check_time_tests() == TIME_TESTS_RUNNING) return false; + if (check_cpu_benchmarks() == CPU_BENCHMARKS_RUNNING) return false; print_log("Polling; active layers:\n"); net_stats.poll(*net_xfers); @@ -706,10 +711,10 @@ int CLIENT_STATE::parse_state_file() { done: fclose(f); - // This was for updating speed stats on the beta + // This was for updating CPU benchmarks on the beta // test, it can be taken out eventually, if (old_major_vers <= 0 && old_minor_vers <= 16) { - run_speed_test = true; + run_cpu_benchmarks = true; } return retval; } @@ -1282,8 +1287,8 @@ void CLIENT_STATE::parse_cmdline(int argc, char** argv) { for (i=1; i")); - else if (match_tag(buf, "")) return 0; + if (match_tag(buf, "")); + else if (match_tag(buf, "")) return 0; else if (parse_double(buf, "", p_fpops)) continue; else if (parse_double(buf, "", p_iops)) continue; else if (parse_double(buf, "", p_membw)) continue; @@ -171,17 +171,15 @@ int HOST_INFO::parse_time_tests(FILE* in) { return 0; } -// Write the time tests for the host information -// -int HOST_INFO::write_time_tests(FILE* out) { +int HOST_INFO::write_cpu_benchmarks(FILE* out) { fprintf(out, - "\n" + "\n" " %f\n" " %f\n" " %f\n" " %f\n" " %f\n" - "\n", + "\n", p_fpops, p_iops, p_membw, diff --git a/client/hostinfo.h b/client/hostinfo.h index a7d4698e15..3868181c95 100644 --- a/client/hostinfo.h +++ b/client/hostinfo.h @@ -55,8 +55,8 @@ struct HOST_INFO { int parse(FILE*); int write(FILE*); - int parse_time_tests(FILE*); - int write_time_tests(FILE*); + int parse_cpu_benchmarks(FILE*); + int write_cpu_benchmarks(FILE*); }; extern bool host_is_running_on_batteries(); diff --git a/client/pers_file_xfer.C b/client/pers_file_xfer.C index e7f1e80508..6d8a10d433 100644 --- a/client/pers_file_xfer.C +++ b/client/pers_file_xfer.C @@ -116,8 +116,15 @@ bool PERS_FILE_XFER::start_xfer() { } if (log_flags.file_xfer) { sprintf(buf, - "Started %s of %s to %s", - (is_upload ? "upload" : "download"), fip->name, fip->get_url() + "Started %s of %s", + (is_upload ? "upload" : "download"), fip->name + ); + show_message(fip->project, buf, MSG_INFO); + } + if (log_flags.file_xfer_debug) { + sprintf(buf, + "URL: %s", + fip->get_url() ); show_message(fip->project, buf, MSG_INFO); } @@ -160,8 +167,16 @@ bool PERS_FILE_XFER::poll(time_t now) { if (log_flags.file_xfer) { sprintf( buf, - "File transfer done for %s; error code %d", - fip->get_url(), fxp->file_xfer_retval + "Finished %s of %s", + is_upload?"upload":"download", fip->name + ); + show_message(fip->project, buf, MSG_INFO); + } + if (log_flags.file_xfer_debug) { + sprintf( + buf, + "file transfer status %d", + fxp->file_xfer_retval ); show_message(fip->project, buf, MSG_INFO); } diff --git a/client/speed_stats.h b/client/speed_stats.h index 501883772e..e8b6050bbb 100644 --- a/client/speed_stats.h +++ b/client/speed_stats.h @@ -10,18 +10,18 @@ #define NUM_DOUBLES 28 #define NUM_INTS 28 -#define CACHE_MIN 1024 /* smallest cache (in words) */ -#define CACHE_MAX 512*1024 /* largest cache */ -#define STRIDE_MIN 1 /* smallest stride (in words) */ -#define STRIDE_MAX 128 /* largest stride */ -#define SAMPLE 10 /* to get a larger time sample */ +#define CACHE_MIN 1024 // smallest cache (in words) +#define CACHE_MAX 512*1024 // largest cache +#define STRIDE_MIN 1 // smallest stride (in words) +#define STRIDE_MAX 128 // largest stride +#define SAMPLE 10 // to get a larger time sample #define SECS_PER_RUN 0.2 -#define MAX_TIME_TESTS_SECONDS 60 -#define TIME_TESTS_RUNNING 0 -#define TIME_TESTS_COMPLETE 1 -#define TIME_TESTS_NOT_RUNNING 2 -#define TIME_TESTS_ERROR 3 +#define MAX_CPU_BENCHMARKS_SECONDS 60 +#define CPU_BENCHMARKS_RUNNING 0 +#define CPU_BENCHMARKS_COMPLETE 1 +#define CPU_BENCHMARKS_NOT_RUNNING 2 +#define CPU_BENCHMARKS_ERROR 3 int check_cache_size( int mem_size ); double double_flop_test( int iterations, int print_debug ); diff --git a/db/constraints.sql b/db/constraints.sql index 05db852536..8575b9b36a 100644 --- a/db/constraints.sql +++ b/db/constraints.sql @@ -31,7 +31,7 @@ alter table workunit alter table result add unique(name), add index res_wuid (workunitid), - add index ind_res_st (server_state), + add index ind_res_st (server_state, random), add index res_filedel (file_delete_state); alter table host diff --git a/db/db.h b/db/db.h index 1d50784b59..71dff23147 100644 --- a/db/db.h +++ b/db/db.h @@ -298,6 +298,7 @@ struct RESULT { double claimed_credit; // CPU time times host credit/sec double granted_credit; // == canonical credit of WU int opaque; // project-specific; usually external ID + int random; // determines send order // the following not used in the DB char wu_name[256]; diff --git a/db/db_mysql.C b/db/db_mysql.C index 8494578277..5b58003503 100644 --- a/db/db_mysql.C +++ b/db/db_mysql.C @@ -298,14 +298,14 @@ void BOINC_MYSQL_DB::struct_to_str(void* vp, char* q, int type) { "name='%s', cpu_time=%f, " "xml_doc_in='%s', xml_doc_out='%s', stderr_out='%s', " "batch=%d, file_delete_state=%d, validate_state=%d, " - "claimed_credit=%f, granted_credit=%f, opaque=%d", + "claimed_credit=%f, granted_credit=%f, opaque=%d, random=%d", rp->id, rp->create_time, rp->workunitid, rp->server_state, rp->outcome, rp->client_state, rp->hostid, rp->report_deadline, rp->sent_time, rp->received_time, rp->name, rp->cpu_time, rp->xml_doc_in, rp->xml_doc_out, rp->stderr_out, rp->batch, rp->file_delete_state, rp->validate_state, - rp->claimed_credit, rp->granted_credit, rp->opaque + rp->claimed_credit, rp->granted_credit, rp->opaque, rp->random ); unescape_single_quotes(rp->xml_doc_out); unescape_single_quotes(rp->stderr_out); @@ -505,6 +505,7 @@ void BOINC_MYSQL_DB::row_to_struct(MYSQL_ROW& r, void* vp, int type) { rp->claimed_credit = atof(r[i++]); rp->granted_credit = atof(r[i++]); rp->opaque = atoi(r[i++]); + rp->random = atoi(r[i++]); break; case TYPE_WORKSEQ: wsp = (WORKSEQ*)vp; @@ -860,7 +861,7 @@ int db_result_enum_server_state(RESULT& p, int limit) { static ENUM e; char buf[256]; - if (!e.active) sprintf(buf, "where server_state=%d", p.server_state); + if (!e.active) sprintf(buf, "where server_state=%d order by random", p.server_state); return boinc_db.db_enum(e, &p, TYPE_RESULT, buf, limit); } diff --git a/db/schema.sql b/db/schema.sql index 7b018c8a8a..066e475682 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -174,6 +174,7 @@ create table result ( claimed_credit double not null, granted_credit double not null, opaque integer not null, + random integer not null, primary key (id) ); diff --git a/html/user/prefs.inc b/html/user/prefs.inc index 3b6d9b0e68..015bdec01e 100644 --- a/html/user/prefs.inc +++ b/html/user/prefs.inc @@ -14,10 +14,10 @@ // // 1.3 // ... -// +// // // ... -// +// // // // and diff --git a/html/user/user.inc b/html/user/user.inc index 4bc709bb03..3f93530195 100644 --- a/html/user/user.inc +++ b/html/user/user.inc @@ -36,8 +36,8 @@ function show_user_profile_private($user) { row2("Postal code", $user->postal_code); row2("", "Edit account info"); row1("Your preferences"); - row2("General", "View"); - row2(PROJECT, "View"); + row2("General", "View/edit"); + row2(PROJECT, "View/edit"); } // show summary of dynamic and static info (public) diff --git a/sched/make_work.C b/sched/make_work.C index bc820d6b8c..002159e98f 100644 --- a/sched/make_work.C +++ b/sched/make_work.C @@ -220,16 +220,17 @@ int main(int argc, char** argv) { exit(1); } + if (lock_file(LOCKFILE)) { + fprintf(stderr, "Another copy of make_work is already running\n"); + exit(1); + } + if (asynch) { if (fork()) { exit(0); } } - if (lock_file(LOCKFILE)) { - fprintf(stderr, "Another copy of make_work is already running\n"); - exit(1); - } - + srand48(getpid() + time(0)); make_work(); } diff --git a/test/test_1sec.php b/test/test_1sec.php index bb09e553f6..f55903bb47 100644 --- a/test/test_1sec.php +++ b/test/test_1sec.php @@ -52,7 +52,7 @@ $project1->start_servers(); $project2->start_servers(); - $host->run("-exit_when_idle -no_time_test"); + $host->run("-exit_when_idle -skip_cpu_benchmarks"); $project1->stop(); $project2->stop(); diff --git a/test/test_backend.php b/test/test_backend.php index e407e8509e..b9c26ae9dc 100644 --- a/test/test_backend.php +++ b/test/test_backend.php @@ -56,7 +56,7 @@ $project->start_servers(); // Run the client until there's no more work - $host->run("-exit_when_idle -no_time_test"); + $host->run("-exit_when_idle -skip_cpu_benchmarks"); sleep(5); diff --git a/test/test_uc.php b/test/test_uc.php index 88a6631833..6678770e26 100644 --- a/test/test_uc.php +++ b/test/test_uc.php @@ -43,7 +43,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->redundancy = 10; + $work->redundancy = 2; $work->delay_bound = 2; // Say that 1 WU takes 1 day on a ref comp $work->rsc_fpops = 86400*1e9/2; @@ -52,7 +52,7 @@ $work->install($project); $project->start_servers(); - $host->run("-exit_when_idle -no_time_test"); + $host->run("-exit_when_idle -skip_cpu_benchmarks"); $project->stop(); $project->validate($app, 2); diff --git a/todo b/todo index efa8f6739e..f03ff3a497 100755 --- a/todo +++ b/todo @@ -56,6 +56,15 @@ Limit frequency of disk writes MEDIUM-PRIORITY (should do before public release) ----------------------- +abort result if any file exceeds max_nbytes + +per-WU limits + max disk + max CPU + max VM size + +Don't fork CPU benchmark process if skip_cpu_benchmarks is set + let user choose language files in installation process write general language file manipulation functions diff --git a/tools/backend_lib.C b/tools/backend_lib.C index 3b487ca959..4867020e00 100644 --- a/tools/backend_lib.C +++ b/tools/backend_lib.C @@ -192,6 +192,7 @@ int create_result( upload_url, download_url ); strcpy(r.xml_doc_in, result_template_copy); + r.random = lrand48(); retval = db_result_new(r); if (retval) {