diff --git a/client/app.cpp b/client/app.cpp index db9bcecc743..8b3347cac42 100644 --- a/client/app.cpp +++ b/client/app.cpp @@ -657,9 +657,9 @@ int ACTIVE_TASK::get_free_slot(RESULT* rp) { // paranoia - don't allow unbounded slots // - if (j > gstate.ncpus*100) { + if (j > gstate.n_usable_cpus*100) { msg_printf(rp->project, MSG_INTERNAL_ERROR, - "exceeded limit of %d slot directories", gstate.ncpus*100 + "exceeded limit of %d slot directories", gstate.n_usable_cpus*100 ); return ERR_NULL; } @@ -1205,16 +1205,14 @@ void* throttler(void*) { while (1) { client_mutex.lock(); - if (gstate.tasks_suspended - || gstate.global_prefs.cpu_usage_limit > 99 - || gstate.global_prefs.cpu_usage_limit < 0.005 - ) { + double limit = gstate.current_cpu_usage_limit(); + if (gstate.tasks_suspended || limit == 0) { client_mutex.unlock(); // ::Sleep((int)(1000*10)); // for Win debugging boinc_sleep(10); continue; } - double on, off, on_frac = gstate.global_prefs.cpu_usage_limit / 100; + double on, off, on_frac = limit / 100; #if 0 // sub-second CPU throttling // DOESN'T WORK BECAUSE OF 1-SEC API POLL diff --git a/client/app_control.cpp b/client/app_control.cpp index 60ac606c190..b1e1427c4d3 100644 --- a/client/app_control.cpp +++ b/client/app_control.cpp @@ -1546,7 +1546,7 @@ void ACTIVE_TASK_SET::get_msgs() { last_time = gstate.now; double et_diff = delta_t; - double et_diff_throttle = delta_t * gstate.global_prefs.cpu_usage_limit/100; + double et_diff_throttle = delta_t * gstate.current_cpu_usage_limit()/100; for (i=0; i 0) { @@ -626,7 +626,7 @@ int CLIENT_STATE::init() { // host_info.p_vm_extensions_disabled = false; - set_ncpus(); + set_n_usable_cpus(); show_host_info(); // this follows parse_state_file() because that's where we read project names @@ -992,6 +992,8 @@ bool CLIENT_STATE::poll_slow_events() { #endif if (user_active != old_user_active) { + set_n_usable_cpus(); + // if niu_max_ncpus_pct pref is set, # usable CPUs may change request_schedule_cpus(user_active?"Not idle":"Idle"); } diff --git a/client/client_state.h b/client/client_state.h index 40bdb84155b..a3439d823fb 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -18,7 +18,6 @@ #ifndef BOINC_CLIENT_STATE_H #define BOINC_CLIENT_STATE_H -#define NEW_CPU_THROTTLE // do CPU throttling using a separate thread. // This makes it possible to throttle faster than the client's 1-sec poll period // NOTE: we can't actually do this because the runtime system's @@ -35,9 +34,7 @@ using std::vector; #include "coproc.h" #include "util.h" -#ifdef NEW_CPU_THROTTLE #include "thread.h" -#endif #include "acct_mgr.h" #include "acct_setup.h" @@ -345,7 +342,7 @@ struct CLIENT_STATE { // - an app fails to start (CS::schedule_cpus()) // - any project op is done via RPC (suspend/resume) // - any result op is done via RPC (suspend/resume) - void set_ncpus(); + void set_n_usable_cpus(); // --------------- cs_account.cpp: int add_project( @@ -363,12 +360,13 @@ struct CLIENT_STATE { double get_fraction_done(RESULT* result); int input_files_available(RESULT*, bool, FILE_INFO** f=0); ACTIVE_TASK* lookup_active_task_by_result(RESULT*); - int ncpus; - // Act like there are this many CPUs. + int n_usable_cpus; + // number of usable CPUs // By default this is the # of physical CPUs, // but it can be changed in two ways: - // - type N in the config file - // - type the max_ncpus_pct pref + // - N in cc_config.xml + // (for debugging; can be > # physical CPUs) + // - the max_ncpus_pct and niu_max_ncpus_pct prefs int latest_version(APP*, char*); int app_finished(ACTIVE_TASK&); @@ -426,6 +424,7 @@ struct CLIENT_STATE { const char* fname = GLOBAL_PREFS_FILE_NAME, const char* override_fname = GLOBAL_PREFS_OVERRIDE_FILE ); + void print_global_prefs(); int save_global_prefs(const char* prefs, char* url, char* sched); double available_ram(); double max_available_ram(); @@ -521,6 +520,24 @@ struct CLIENT_STATE { #endif KEYWORDS keywords; + + double current_cpu_usage_limit() { + double x = global_prefs.cpu_usage_limit; + if (!user_active && global_prefs.niu_cpu_usage_limit>=0) { + x = global_prefs.niu_cpu_usage_limit; + } + if (x < 0.005 || x > 99.99) { + x = 100; + } + return x; + } + double current_suspend_cpu_usage() { + double x = global_prefs.suspend_cpu_usage; + if (!user_active && global_prefs.niu_suspend_cpu_usage>=0) { + x = global_prefs.niu_suspend_cpu_usage; + } + return x; + } }; extern CLIENT_STATE gstate; @@ -535,10 +552,8 @@ extern double calculate_exponential_backoff( int n, double MIN, double MAX ); -#ifdef NEW_CPU_THROTTLE extern THREAD_LOCK client_mutex; extern THREAD throttle_thread; -#endif //////// TIME-RELATED CONSTANTS //////////// diff --git a/client/cpu_sched.cpp b/client/cpu_sched.cpp index bce568d6087..8f81b6694de 100644 --- a/client/cpu_sched.cpp +++ b/client/cpu_sched.cpp @@ -95,7 +95,7 @@ struct PROC_RESOURCES { COPROCS pr_coprocs; void init() { - ncpus = gstate.ncpus; + ncpus = gstate.n_usable_cpus; ncpus_used_st = 0; ncpus_used_mt = 0; pr_coprocs.clone(coprocs, false); @@ -567,7 +567,7 @@ void CLIENT_STATE::reset_rec_accounting() { // static void update_rec() { double f = gstate.host_info.p_fpops; - double on_frac = gstate.global_prefs.cpu_usage_limit / 100; + double on_frac = gstate.current_cpu_usage_limit() / 100; for (unsigned int i=0; i& runnable_jobs) { vector::iterator cur = runnable_jobs.begin(); while(1) { if (cur == runnable_jobs.end()) break; - if (cpus_used >= gstate.ncpus) break; + if (cpus_used >= gstate.n_usable_cpus) break; RESULT* rp = *cur; if (rp->rr_sim_misses_deadline) break; double nc = rp->avp->avg_ncpus; @@ -1251,9 +1251,9 @@ bool CLIENT_STATE::enforce_run_list(vector& run_list) { // don't allow additional CPU jobs; // allow coproc jobs if the resulting CPU load is at most ncpus+1 // - if (ncpus_used >= ncpus) { + if (ncpus_used >= n_usable_cpus) { if (rp->uses_coprocs()) { - if (ncpus_used + rp->avp->avg_ncpus > ncpus+1) { + if (ncpus_used + rp->avp->avg_ncpus > n_usable_cpus+1) { if (log_flags.cpu_sched_debug) { msg_printf(rp->project, MSG_INFO, "[cpu_sched_debug] skipping GPU job %s; CPU committed", @@ -1266,7 +1266,7 @@ bool CLIENT_STATE::enforce_run_list(vector& run_list) { if (log_flags.cpu_sched_debug) { msg_printf(rp->project, MSG_INFO, "[cpu_sched_debug] all CPUs used (%.2f >= %d), skipping %s", - ncpus_used, ncpus, + ncpus_used, n_usable_cpus, rp->name ); } @@ -1350,11 +1350,11 @@ bool CLIENT_STATE::enforce_run_list(vector& run_list) { } } - if (log_flags.cpu_sched_debug && ncpus_used < ncpus) { + if (log_flags.cpu_sched_debug && ncpus_used < n_usable_cpus) { msg_printf(0, MSG_INFO, "[cpu_sched_debug] using %.2f out of %d CPUs", - ncpus_used, ncpus + ncpus_used, n_usable_cpus ); - if (ncpus_used < ncpus) { + if (ncpus_used < n_usable_cpus) { request_work_fetch("CPUs idle"); } } @@ -1622,12 +1622,14 @@ ACTIVE_TASK* CLIENT_STATE::get_task(RESULT* rp) { return atp; } -// called at startup (after get_host_info()) -// and when general prefs have been parsed. -// NOTE: GSTATE.NCPUS MUST BE 1 OR MORE; WE DIVIDE BY IT IN A COUPLE OF PLACES +// called: +// - at startup (after get_host_info()) +// - when general prefs have been parsed +// - when user_active changes +// NOTE: n_usable_cpus MUST BE 1 OR MORE; WE DIVIDE BY IT IN A COUPLE OF PLACES // -void CLIENT_STATE::set_ncpus() { - int ncpus_old = ncpus; +void CLIENT_STATE::set_n_usable_cpus() { + int ncpus_old = n_usable_cpus; // config file can say to act like host has N CPUs // @@ -1638,25 +1640,29 @@ void CLIENT_STATE::set_ncpus() { first = false; } if (cc_config.ncpus>0) { - ncpus = cc_config.ncpus; - host_info.p_ncpus = ncpus; // use this in scheduler requests + n_usable_cpus = cc_config.ncpus; + host_info.p_ncpus = n_usable_cpus; // use this in scheduler requests } else { host_info.p_ncpus = original_p_ncpus; - ncpus = host_info.p_ncpus; + n_usable_cpus = host_info.p_ncpus; } - if (ncpus <= 0) { - ncpus = 1; // shouldn't happen + + double p = global_prefs.max_ncpus_pct; + if (!user_active && global_prefs.niu_max_ncpus_pct>=0) { + p = global_prefs.niu_max_ncpus_pct; + } + if (p) { + n_usable_cpus = (int)((n_usable_cpus * p)/100); } - if (global_prefs.max_ncpus_pct) { - ncpus = (int)((ncpus * global_prefs.max_ncpus_pct)/100); - if (ncpus == 0) ncpus = 1; + if (n_usable_cpus <= 0) { + n_usable_cpus = 1; } - if (initialized && ncpus != ncpus_old) { + if (initialized && n_usable_cpus != ncpus_old) { msg_printf(0, MSG_INFO, "Number of usable CPUs has changed from %d to %d.", - ncpus_old, ncpus + ncpus_old, n_usable_cpus ); request_schedule_cpus("Number of usable CPUs has changed"); request_work_fetch("Number of usable CPUs has changed"); diff --git a/client/cs_benchmark.cpp b/client/cs_benchmark.cpp index 9020ee9a101..3483419333f 100644 --- a/client/cs_benchmark.cpp +++ b/client/cs_benchmark.cpp @@ -262,9 +262,9 @@ void CLIENT_STATE::start_cpu_benchmarks(bool force) { cpu_benchmarks_start = dtime(); benchmark_descs.clear(); - benchmark_descs.resize(ncpus); + benchmark_descs.resize(n_usable_cpus); - bm_ncpus = ncpus; + bm_ncpus = n_usable_cpus; benchmarks_running = true; for (i=0; i global_prefs.suspend_cpu_usage) { + if (non_boinc_cpu_usage*100 > current_suspend_cpu_usage()) { last_cpu_usage_suspend = now; return SUSPEND_REASON_CPU_USAGE; } @@ -301,26 +301,6 @@ int CLIENT_STATE::check_suspend_processing() { } #endif -#ifndef NEW_CPU_THROTTLE - // CPU throttling. - // Do this check last; that way if suspend_reason is CPU_THROTTLE, - // the GUI knows there's no other source of suspension - // - if (global_prefs.cpu_usage_limit < 99) { // round-off? - static double last_time=0, debt=0; - double diff = now - last_time; - last_time = now; - if (diff >= POLL_INTERVAL/2. && diff < POLL_INTERVAL*10.) { - debt += diff*global_prefs.cpu_usage_limit/100; - if (debt < 0) { - return SUSPEND_REASON_CPU_THROTTLE; - } else { - debt -= diff; - } - } - } -#endif - // CPU is not suspended. See if GPUs are // if (!coprocs.none()) { @@ -668,71 +648,147 @@ void CLIENT_STATE::read_global_prefs( } } +#ifndef SIM + get_disk_usages(); +#endif + set_n_usable_cpus(); + +#ifdef ANDROID + global_prefs.run_if_user_active = false; +#endif +#ifndef SIM + file_xfers->set_bandwidth_limits(true); + file_xfers->set_bandwidth_limits(false); +#endif + print_global_prefs(); + request_schedule_cpus("Prefs update"); + request_work_fetch("Prefs update"); +#ifndef SIM + active_tasks.request_reread_app_info(); +#endif +} + +void CLIENT_STATE::print_global_prefs() { msg_printf(NULL, MSG_INFO, "Preferences:"); + + // in use + // + msg_printf(NULL, MSG_INFO, "- When computer is in use"); msg_printf(NULL, MSG_INFO, - " max memory usage when active: %.2f MB", - (host_info.m_nbytes*global_prefs.ram_max_used_busy_frac)/MEGA + "- 'In use' means mouse/keyboard input in last %.1f minutes", + global_prefs.idle_time_to_run ); + if (!global_prefs.run_if_user_active) { + msg_printf(NULL, MSG_INFO, "- don't compute"); + } + if (!global_prefs.run_gpu_if_user_active) { + msg_printf(NULL, MSG_INFO, "- don't use GPU"); + } + double p = global_prefs.max_ncpus_pct; + if (p) { + int n = (int)((host_info.p_ncpus * p)/100); + msg_printf(NULL, MSG_INFO, + "- max CPUs used: %d", n + ); + } + if (global_prefs.cpu_usage_limit) { + msg_printf(NULL, MSG_INFO, + "- Use at most %.0f%% of the CPU time", + global_prefs.cpu_usage_limit + ); + } + if (global_prefs.suspend_cpu_usage) { + msg_printf(NULL, MSG_INFO, + "- suspend if non-BOINC CPU load exceeds %.0f%%", + global_prefs.suspend_cpu_usage + ); + } msg_printf(NULL, MSG_INFO, - " max memory usage when idle: %.2f MB", - (host_info.m_nbytes*global_prefs.ram_max_used_idle_frac)/MEGA + "- max memory usage: %.2f GB", + (host_info.m_nbytes*global_prefs.ram_max_used_busy_frac)/GIGA ); -#ifndef SIM - get_disk_usages(); + + // not in use + // msg_printf(NULL, MSG_INFO, - " max disk usage: %.2f GB", - allowed_disk_usage(total_disk_usage)/GIGA + "- When computer is not in use" ); -#endif - // max_cpus, bandwidth limits may have changed - // - set_ncpus(); - if (ncpus != host_info.p_ncpus) { + p = global_prefs.niu_max_ncpus_pct; + int n = (int)((host_info.p_ncpus * p)/100); + msg_printf(NULL, MSG_INFO, + "- max CPUs used: %d", n + ); + + msg_printf(NULL, MSG_INFO, + "- Use at most %.0f%% of the CPU time", + global_prefs.niu_cpu_usage_limit + ); + + if (global_prefs.niu_suspend_cpu_usage > 0) { msg_printf(NULL, MSG_INFO, - " max CPUs used: %d", ncpus + "- suspend if non-BOINC CPU load exceeds %.0f%%", + global_prefs.niu_suspend_cpu_usage ); } - if (!global_prefs.run_if_user_active) { - msg_printf(NULL, MSG_INFO, " don't compute while active"); -#ifdef ANDROID - } else { - msg_printf(NULL, MSG_INFO, " Android: don't compute while active"); - global_prefs.run_if_user_active = false; -#endif + msg_printf(NULL, MSG_INFO, + "- max memory usage: %.2f GB", + (host_info.m_nbytes*global_prefs.ram_max_used_idle_frac)/GIGA + ); + if (global_prefs.suspend_if_no_recent_input > 0) { + msg_printf(NULL, MSG_INFO, + "- Suspend if no input in last %f minutes", + global_prefs.suspend_if_no_recent_input + ); } - if (!global_prefs.run_gpu_if_user_active) { - msg_printf(NULL, MSG_INFO, " don't use GPU while active"); + + // general + // + + if (!global_prefs.run_on_batteries) { + msg_printf(NULL, MSG_INFO, + "- Suspend if running on batteries" + ); } - if (global_prefs.suspend_cpu_usage) { + if (global_prefs.leave_apps_in_memory) { msg_printf(NULL, MSG_INFO, - " suspend work if non-BOINC CPU load exceeds %.0f%%", - global_prefs.suspend_cpu_usage + "- Leave apps in memory if not running" ); } + msg_printf(NULL, MSG_INFO, + "- Store at least %.2f days of work", + global_prefs.work_buf_min_days + ); + msg_printf(NULL, MSG_INFO, + "- Store up to an additional %.2f days of work", + global_prefs.work_buf_additional_days + ); + + // network + // if (global_prefs.max_bytes_sec_down) { msg_printf(NULL, MSG_INFO, - " max download rate: %.0f bytes/sec", + "- max download rate: %.0f bytes/sec", global_prefs.max_bytes_sec_down ); } if (global_prefs.max_bytes_sec_up) { msg_printf(NULL, MSG_INFO, - " max upload rate: %.0f bytes/sec", + "- max upload rate: %.0f bytes/sec", global_prefs.max_bytes_sec_up ); } + + // disk + // #ifndef SIM - file_xfers->set_bandwidth_limits(true); - file_xfers->set_bandwidth_limits(false); -#endif msg_printf(NULL, MSG_INFO, - " (to change preferences, visit a project web site or select Preferences in the Manager)" + "- max disk usage: %.2f GB", + allowed_disk_usage(total_disk_usage)/GIGA ); - request_schedule_cpus("Prefs update"); - request_work_fetch("Prefs update"); -#ifndef SIM - active_tasks.request_reread_app_info(); #endif + msg_printf(NULL, MSG_INFO, + "- (to change preferences, visit a project web site or select Preferences in the Manager)" + ); } int CLIENT_STATE::save_global_prefs( diff --git a/client/cs_scheduler.cpp b/client/cs_scheduler.cpp index eafccd5e136..6923e775a6e 100644 --- a/client/cs_scheduler.cpp +++ b/client/cs_scheduler.cpp @@ -211,7 +211,7 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p) { // update hardware info, and write host info // host_info.get_host_info(false); - set_ncpus(); + set_n_usable_cpus(); host_info.write(mf, !cc_config.suppress_net_info, false); // get and write disk usage diff --git a/client/gui_rpc_server_ops.cpp b/client/gui_rpc_server_ops.cpp index 7698112a6f1..31770c3a917 100644 --- a/client/gui_rpc_server_ops.cpp +++ b/client/gui_rpc_server_ops.cpp @@ -636,7 +636,7 @@ static void handle_reset_host_info(GUI_RPC_CONN& grc) { gstate.host_info.get_host_info(true); // the amount of RAM or #CPUs may have changed // - gstate.set_ncpus(); + gstate.set_n_usable_cpus(); gstate.request_schedule_cpus("reset_host_info"); gstate.show_host_info(); grc.mfout.printf("\n"); @@ -1331,7 +1331,7 @@ static void handle_read_cc_config(GUI_RPC_CONN& grc) { read_config_file(false); cc_config.show(); log_flags.show(); - gstate.set_ncpus(); + gstate.set_n_usable_cpus(); process_gpu_exclusions(); // also reread app_config.xml files @@ -1349,12 +1349,12 @@ static void handle_get_daily_xfer_history(GUI_RPC_CONN& grc) { #ifdef __APPLE__ static void stop_graphics_app(pid_t thePID, - long iBrandID, - char current_dir[], - char switcher_path[], - string theScreensaverLoginUser, - GUI_RPC_CONN& grc - ) { + long iBrandID, + char current_dir[], + char switcher_path[], + string theScreensaverLoginUser, + GUI_RPC_CONN& grc +) { char* argv[16]; int argc; char screensaverLoginUser[256]; @@ -1365,19 +1365,19 @@ static void stop_graphics_app(pid_t thePID, char pidString[10]; snprintf(pidString, sizeof(pidString), "%d", thePID); - #if 1 +#if 1 argv[0] = const_cast(SWITCHER_FILE_NAME); argv[1] = saverName[iBrandID]; argv[2] = "-kill_gfx"; argv[3] = pidString; argc = 4; - #else +#else argv[0] = const_cast(SWITCHER_FILE_NAME); argv[1] = "/bin/kill"; argv[2] = "-kill"; argv[3] = (char *)pidString; argc = 4; - #endif +#endif if (!theScreensaverLoginUser.empty()) { argv[argc++] = "--ScreensaverLoginUser"; safe_strcpy(screensaverLoginUser, theScreensaverLoginUser.c_str()); diff --git a/client/rr_sim.cpp b/client/rr_sim.cpp index 73b4d8bef38..2320ea65e90 100644 --- a/client/rr_sim.cpp +++ b/client/rr_sim.cpp @@ -368,7 +368,7 @@ void RR_SIM::pick_jobs_to_run(double reltime) { continue; } } else { - if (rsc_work_fetch[rt].sim_nused >= gstate.ncpus) break; + if (rsc_work_fetch[rt].sim_nused >= gstate.n_usable_cpus) break; } ++rsc_pwf.pending_iter; } @@ -403,7 +403,7 @@ void RR_SIM::pick_jobs_to_run(double reltime) { // after the initial assignment of jobs // static void record_nidle_now() { - rsc_work_fetch[0].nidle_now = gstate.ncpus - rsc_work_fetch[0].sim_nused; + rsc_work_fetch[0].nidle_now = gstate.n_usable_cpus - rsc_work_fetch[0].sim_nused; if (rsc_work_fetch[0].nidle_now < 0) rsc_work_fetch[0].nidle_now = 0; for (int i=1; i& ip_results) { IP_RESULT ipr(rp->name, rp->report_deadline-now, x); ip_results.push_back(ipr); } - //init_ip_results(work_buf_min(), ncpus, ip_results); - init_ip_results(0, ncpus, ip_results); + //init_ip_results(work_buf_min(), n_usable_ncpus, ip_results); + init_ip_results(0, n_usable_cpus, ip_results); } void get_apps_needing_work(PROJECT* p, vector& apps) { @@ -412,7 +412,7 @@ bool CLIENT_STATE::simulate_rpc(PROJECT* p) { double et = wup->rsc_fpops_est / rp->avp->flops; if (server_uses_workload) { IP_RESULT c(rp->name, rp->report_deadline-now, et); - if (check_candidate(c, ncpus, ip_results)) { + if (check_candidate(c, n_usable_cpus, ip_results)) { ip_results.push_back(c); } else { msg_printf(p, MSG_INFO, "job for %s misses deadline sim\n", rp->app->name); @@ -600,8 +600,8 @@ bool ACTIVE_TASK_SET::poll() { // if CPU is overcommitted, compute cpu_scale // double cpu_scale = 1; - if (cpu_usage > gstate.ncpus) { - cpu_scale = (gstate.ncpus - cpu_usage_gpu) / (cpu_usage - cpu_usage_gpu); + if (cpu_usage > gstate.n_usable_cpus) { + cpu_scale = (gstate.n_usable_cpus - cpu_usage_gpu) / (cpu_usage - cpu_usage_gpu); } double used = 0; @@ -1495,7 +1495,7 @@ void do_client_simulation() { clear_backoff(); gstate.log_show_projects(); - gstate.set_ncpus(); + gstate.set_n_usable_cpus(); work_fetch.init(); //set_initial_rec(); diff --git a/client/work_fetch.cpp b/client/work_fetch.cpp index 31d105f8a68..e54cb0ab3d2 100644 --- a/client/work_fetch.cpp +++ b/client/work_fetch.cpp @@ -1077,7 +1077,7 @@ void WORK_FETCH::set_initial_work_request(PROJECT* p) { // called once, at client startup // void WORK_FETCH::init() { - rsc_work_fetch[0].init(0, gstate.ncpus, 1); + rsc_work_fetch[0].init(0, gstate.n_usable_cpus, 1); double cpu_flops = gstate.host_info.p_fpops; // use 20% as a rough estimate of GPU efficiency @@ -1127,7 +1127,7 @@ void CLIENT_STATE::compute_nuploading_results() { rp->project->nuploading_results++; } } - int n = gstate.ncpus; + int n = gstate.n_usable_cpus; for (int j=1; j n) { n = coprocs.coprocs[j].count; diff --git a/clientgui/DlgAdvPreferences.cpp b/clientgui/DlgAdvPreferences.cpp index 2fb34f6f54b..6f09b317a38 100644 --- a/clientgui/DlgAdvPreferences.cpp +++ b/clientgui/DlgAdvPreferences.cpp @@ -131,7 +131,9 @@ void CDlgAdvPreferences::SetValidators() { // ######### proc usage page m_txtProcUseProcessors->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_txtProcUseProcessorsNotInUse->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_txtProcUseCPUTime->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_txtProcUseCPUTimeNotInUse->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_txtProcIdleFor->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_txtProcIdleFor->SetMaxLength(16); @@ -275,8 +277,30 @@ void CDlgAdvPreferences::DisplayValue(double value, wxTextCtrl* textCtrl, wxChec textCtrl->Enable(); } +void CDlgAdvPreferences::EnableDisableInUseItem(wxTextCtrl* textCtrl, bool doEnable, double value) { + if (doEnable) { + if (! textCtrl->IsEnabled()) { + textCtrl->Enable(); + DisplayValue(value, textCtrl); + } + } else { + textCtrl->Clear(); + textCtrl->Disable(); + } +} + +void CDlgAdvPreferences::EnableDisableInUseItems() { + bool doEnable = !(m_chkProcInUse->IsChecked()); + EnableDisableInUseItem(m_txtProcUseProcessors, doEnable, + prefs.max_ncpus_pct > 0.0 ? prefs.max_ncpus_pct : 100.0); + EnableDisableInUseItem(m_txtProcUseCPUTime, doEnable, prefs.cpu_usage_limit); + m_chkMaxLoad->Enable(doEnable); + EnableDisableInUseItem(m_txtMaxLoad, doEnable && m_chkMaxLoad->IsChecked(), prefs.suspend_cpu_usage); + EnableDisableInUseItem(m_txtMemoryMaxInUse, doEnable, prefs.ram_max_used_busy_frac*100.0); +} -/* read preferences from core client and initialize control values */ +// read preferences from core client and initialize control values +// void CDlgAdvPreferences::ReadPreferenceSettings() { CMainDocument* pDoc = wxGetApp().GetDocument(); int retval; @@ -303,11 +327,15 @@ void CDlgAdvPreferences::ReadPreferenceSettings() { // 0 means "no restriction" but we don't use a checkbox here if (prefs.max_ncpus_pct == 0.0) prefs.max_ncpus_pct = 100.0; DisplayValue(prefs.max_ncpus_pct, m_txtProcUseProcessors); + if (prefs.niu_max_ncpus_pct == 0.0) prefs.niu_max_ncpus_pct = 100.0; + DisplayValue(prefs.niu_max_ncpus_pct, m_txtProcUseProcessorsNotInUse); - //cpu limit + // cpu limit // 0 means "no restriction" but we don't use a checkbox here if (prefs.cpu_usage_limit == 0.0) prefs.cpu_usage_limit = 100.0; DisplayValue(prefs.cpu_usage_limit, m_txtProcUseCPUTime); + if (prefs.niu_cpu_usage_limit == 0.0) prefs.niu_cpu_usage_limit = 100.0; + DisplayValue(prefs.niu_cpu_usage_limit, m_txtProcUseCPUTimeNotInUse); // on batteries m_chkProcOnBatteries->SetValue(! prefs.run_on_batteries); @@ -332,9 +360,13 @@ void CDlgAdvPreferences::ReadPreferenceSettings() { m_txtProcIdleFor->Disable(); } - DisplayValue(prefs.suspend_if_no_recent_input, m_txtNoRecentInput); + m_chkNoRecentInput->SetValue(prefs.suspend_if_no_recent_input > 0.0); + DisplayValue(prefs.suspend_if_no_recent_input, m_txtNoRecentInput, m_chkNoRecentInput); + m_chkMaxLoad->SetValue(prefs.suspend_cpu_usage > 0.0); DisplayValue(prefs.suspend_cpu_usage, m_txtMaxLoad, m_chkMaxLoad); + m_chkMaxLoadNotInUse->SetValue(prefs.niu_suspend_cpu_usage > 0.0); + DisplayValue(prefs.niu_suspend_cpu_usage, m_txtMaxLoadNotInUse, m_chkMaxLoadNotInUse); // connection interval DisplayValue(prefs.work_buf_min_days, m_txtNetConnectInterval); @@ -434,22 +466,32 @@ void CDlgAdvPreferences::ReadPreferenceSettings() { this->UpdateControlStates(); } -/* write overridden preferences to disk (global_prefs_override.xml) */ -/* IMPORTANT: Any items added here must be checked in ValidateInput()! */ +// write overridden preferences to disk (global_prefs_override.xml) +// IMPORTANT: Any items added here must be checked in ValidateInput()! +// bool CDlgAdvPreferences::SavePreferencesSettings() { double td; mask.clear(); // ######### proc usage page - m_txtProcUseProcessors->GetValue().ToDouble(&td); - prefs.max_ncpus_pct = RoundToHundredths(td); - mask.max_ncpus_pct=true; - - // - m_txtProcUseCPUTime->GetValue().ToDouble(&td); - prefs.cpu_usage_limit=RoundToHundredths(td); - mask.cpu_usage_limit=true; + if (m_txtProcUseProcessors->IsEnabled()) { + m_txtProcUseProcessors->GetValue().ToDouble(&td); + prefs.max_ncpus_pct = RoundToHundredths(td); + mask.max_ncpus_pct=true; + } + m_txtProcUseProcessorsNotInUse->GetValue().ToDouble(&td); + prefs.niu_max_ncpus_pct = RoundToHundredths(td); + mask.niu_max_ncpus_pct=true; + + if (m_txtProcUseCPUTime->IsEnabled()) { + m_txtProcUseCPUTime->GetValue().ToDouble(&td); + prefs.cpu_usage_limit=RoundToHundredths(td); + mask.cpu_usage_limit=true; + } + m_txtProcUseCPUTimeNotInUse->GetValue().ToDouble(&td); + prefs.niu_cpu_usage_limit = RoundToHundredths(td); + mask.niu_cpu_usage_limit = true; prefs.run_on_batteries = ! (m_chkProcOnBatteries->GetValue()); mask.run_on_batteries=true; @@ -466,13 +508,15 @@ bool CDlgAdvPreferences::SavePreferencesSettings() { mask.idle_time_to_run=true; } - // - m_txtNoRecentInput->GetValue().ToDouble(&td); - prefs.suspend_if_no_recent_input = RoundToHundredths(td); - mask.suspend_if_no_recent_input = true; + if (m_chkNoRecentInput->IsChecked()) { + m_txtNoRecentInput->GetValue().ToDouble(&td); + prefs.suspend_if_no_recent_input = RoundToHundredths(td); + } else { + prefs.suspend_if_no_recent_input = 0; + } + mask.suspend_if_no_recent_input = true; - // - if (m_chkMaxLoad->IsChecked()) { + if (m_txtMaxLoad->IsEnabled()) { m_txtMaxLoad->GetValue().ToDouble(&td); prefs.suspend_cpu_usage=RoundToHundredths(td); } else { @@ -480,6 +524,14 @@ bool CDlgAdvPreferences::SavePreferencesSettings() { } mask.suspend_cpu_usage=true; + if (m_chkMaxLoadNotInUse->IsChecked()) { + m_txtMaxLoadNotInUse->GetValue().ToDouble(&td); + prefs.niu_suspend_cpu_usage=RoundToHundredths(td); + } else { + prefs.niu_suspend_cpu_usage = 0.0; + } + mask.niu_suspend_cpu_usage=true; + m_txtNetConnectInterval->GetValue().ToDouble(&td); prefs.work_buf_min_days=RoundToHundredths(td); mask.work_buf_min_days=true; @@ -568,11 +620,13 @@ bool CDlgAdvPreferences::SavePreferencesSettings() { } mask.disk_max_used_pct=true; //Memory - m_txtMemoryMaxInUse->GetValue().ToDouble(&td); - td = RoundToHundredths(td); - td = td / 100.0; - prefs.ram_max_used_busy_frac=td; - mask.ram_max_used_busy_frac=true; + if (m_txtMemoryMaxInUse->IsEnabled()) { + m_txtMemoryMaxInUse->GetValue().ToDouble(&td); + td = RoundToHundredths(td); + td = td / 100.0; + prefs.ram_max_used_busy_frac=td; + mask.ram_max_used_busy_frac=true; + } // m_txtMemoryMaxOnIdle->GetValue().ToDouble(&td); td = RoundToHundredths(td); @@ -652,7 +706,9 @@ void CDlgAdvPreferences::UpdateControlStates() { m_chkGPUProcInUse->Enable(! m_chkProcInUse->IsChecked()); if (m_chkProcInUse->IsChecked()) m_chkGPUProcInUse->SetValue(true); - m_txtMaxLoad->Enable(m_chkMaxLoad->IsChecked()); + m_txtMaxLoadNotInUse->Enable(m_chkMaxLoadNotInUse->IsChecked()); + EnableDisableInUseItems(); + m_txtNoRecentInput->Enable(m_chkNoRecentInput->IsChecked()); // ######### disk and memory usage page m_txtDiskMaxSpace->Enable(m_chkDiskMaxSpace->IsChecked()); @@ -692,15 +748,22 @@ bool CDlgAdvPreferences::ValidateInput() { double startTime, endTime; // ######### proc usage page - buffer = m_txtProcUseProcessors->GetValue(); + if (m_txtProcUseProcessors->IsEnabled()) { + buffer = m_txtProcUseProcessors->GetValue(); + if(!IsValidFloatValueBetween(buffer, 0.0, 100.0)) { + ShowErrorMessage(invMsgLimit100, m_txtProcUseProcessors); + return false; + } + } + buffer = m_txtProcUseProcessorsNotInUse->GetValue(); if(!IsValidFloatValueBetween(buffer, 0.0, 100.0)) { - ShowErrorMessage(invMsgLimit100, m_txtProcUseProcessors); + ShowErrorMessage(invMsgLimit100, m_txtProcUseProcessorsNotInUse); return false; } - buffer = m_txtProcUseCPUTime->GetValue(); + buffer = m_txtProcUseCPUTimeNotInUse->GetValue(); if(!IsValidFloatValueBetween(buffer, 0.0, 100.0)) { - ShowErrorMessage(invMsgLimit100, m_txtProcUseCPUTime); + ShowErrorMessage(invMsgLimit100, m_txtProcUseCPUTimeNotInUse); return false; } @@ -712,13 +775,15 @@ bool CDlgAdvPreferences::ValidateInput() { } } - buffer = m_txtNoRecentInput->GetValue(); - if (!IsValidFloatValueBetween(buffer, 0, 9999999999999.99)) { - ShowErrorMessage(invMsgFloat, m_txtNoRecentInput); - return false; + if (m_chkNoRecentInput->IsChecked()) { + buffer = m_txtNoRecentInput->GetValue(); + if (!IsValidFloatValueBetween(buffer, 0, 9999999999999.99)) { + ShowErrorMessage(invMsgFloat, m_txtNoRecentInput); + return false; + } } - if (m_chkMaxLoad->IsChecked()) { + if (m_txtMaxLoad->IsEnabled()) { buffer = m_txtMaxLoad->GetValue(); if(!IsValidFloatValueBetween(buffer, 1.0, 100.0)) { ShowErrorMessage(invMsgLimit1_100, m_txtMaxLoad); @@ -726,7 +791,15 @@ bool CDlgAdvPreferences::ValidateInput() { } } - //limit additional days from 0 to 10 + if (m_chkMaxLoadNotInUse->IsChecked()) { + buffer = m_txtMaxLoadNotInUse->GetValue(); + if(!IsValidFloatValueBetween(buffer, 1.0, 100.0)) { + ShowErrorMessage(invMsgLimit1_100, m_txtMaxLoadNotInUse); + return false; + } + } + + // limit additional days from 0 to 10 buffer = m_txtNetConnectInterval->GetValue(); if(!IsValidFloatValueBetween(buffer, 0.0, 10.0)) { ShowErrorMessage(invMsgLimit10,m_txtNetConnectInterval); @@ -808,10 +881,12 @@ bool CDlgAdvPreferences::ValidateInput() { } } - buffer = m_txtMemoryMaxInUse->GetValue(); - if(!IsValidFloatValueBetween(buffer, 1.0, 100.0)) { - ShowErrorMessage(invMsgLimit1_100, m_txtMemoryMaxInUse); - return false; + if(m_txtMemoryMaxInUse->IsEnabled()) { + buffer = m_txtMemoryMaxInUse->GetValue(); + if(!IsValidFloatValueBetween(buffer, 1.0, 100.0)) { + ShowErrorMessage(invMsgLimit1_100, m_txtMemoryMaxInUse); + return false; + } } buffer = m_txtMemoryMaxOnIdle->GetValue(); @@ -1035,7 +1110,12 @@ void CDlgAdvPreferences::OnHandleCommandEvent(wxCommandEvent& ev) { case ID_CHKMAXLOAD: DisplayValue(defaultPrefs.suspend_cpu_usage, m_txtMaxLoad, m_chkMaxLoad); break; - + case ID_CHKMAXLOADNOTINUSE: + DisplayValue(defaultPrefs.niu_suspend_cpu_usage, m_txtMaxLoadNotInUse, m_chkMaxLoadNotInUse); + break; + case ID_CHKNORECENTINPUT: + DisplayValue(defaultPrefs.suspend_if_no_recent_input, m_txtNoRecentInput, m_chkNoRecentInput); + break; // network usage page case ID_CHKNETDOWNLOADRATE: DisplayValue((defaultPrefs.max_bytes_sec_down / 1024), m_txtNetDownloadRate, m_chkNetDownloadRate); diff --git a/clientgui/DlgAdvPreferences.h b/clientgui/DlgAdvPreferences.h index 220c6a90a29..365e530f065 100644 --- a/clientgui/DlgAdvPreferences.h +++ b/clientgui/DlgAdvPreferences.h @@ -59,6 +59,8 @@ class CDlgAdvPreferences : public CDlgAdvPreferencesBase { void OnHelp(wxCommandEvent& event); void OnClear(wxCommandEvent& event); void DisplayValue(double value, wxTextCtrl* textCtrl, wxCheckBox* checkBox=NULL); + void EnableDisableInUseItem(wxTextCtrl* textCtrl, bool doEnable, double value); + void EnableDisableInUseItems(); bool OKToShow() { return m_bOKToShow; } private: GLOBAL_PREFS prefs; diff --git a/clientgui/DlgAdvPreferencesBase.cpp b/clientgui/DlgAdvPreferencesBase.cpp index 11cc1b20f24..ce23d3056b4 100644 --- a/clientgui/DlgAdvPreferencesBase.cpp +++ b/clientgui/DlgAdvPreferencesBase.cpp @@ -85,15 +85,16 @@ CDlgAdvPreferencesBase::CDlgAdvPreferencesBase( wxWindow* parent, int id, wxStri if (m_bUsingLocalPrefs) { legendSizer->Add( new wxStaticText( topControlsStaticBox, ID_DEFAULT, - _("Using local preferences.\n" - "Click \"Use web prefs\" to use web-based preferences from" - ), wxDefaultPosition, wxDefaultSize, 0 ), + _("Using local prefs.") + + " " + +_("Click to use web prefs from"), + wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 1 ); } else { legendSizer->Add( new wxStaticText( topControlsStaticBox, ID_DEFAULT, - _("Using web-based preferences from"), + _("Using web prefs from"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 1 ); @@ -110,7 +111,7 @@ CDlgAdvPreferencesBase::CDlgAdvPreferencesBase( wxWindow* parent, int id, wxStri if (!m_bUsingLocalPrefs) { legendSizer->Add( new wxStaticText( topControlsStaticBox, ID_DEFAULT, - _("Set values and click Save to use local preferences instead."), + _("Set values and click Save to use local prefs instead."), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 1 ); @@ -154,9 +155,9 @@ CDlgAdvPreferencesBase::CDlgAdvPreferencesBase( wxWindow* parent, int id, wxStri iImageIndex = pImageList->Add(wxBitmap(xfer_xpm)); m_Notebook->AddPage( m_panelNetwork, _("Network"), true, iImageIndex ); - m_panelDiskAndMemory = createDiskAndMemoryTab(m_Notebook); + m_panelDisk = createDiskTab(m_Notebook); iImageIndex = pImageList->Add(wxBitmap(usage_xpm)); - m_Notebook->AddPage( m_panelDiskAndMemory, _("Disk and memory"), true, iImageIndex ); + m_Notebook->AddPage( m_panelDisk, _("Disk"), true, iImageIndex ); m_panelDailySchedules = createDailySchedulesTab(m_Notebook); iImageIndex = pImageList->Add(wxBitmap(clock_xpm)); @@ -201,45 +202,73 @@ CDlgAdvPreferencesBase::CDlgAdvPreferencesBase( wxWindow* parent, int id, wxStri this->SetSizer( dialogSizer ); } +#define PAD0 1 +#define PAD1 3 + +// this version lets you attach different tooltips to different items +// +void CDlgAdvPreferencesBase::add_row_to_sizer2(wxSizer* toSizer, + wxWindow* item1, wxString& tt1, + wxWindow* item2, wxString& tt2, + wxWindow* item3, wxString& tt3, + wxWindow* item4, wxString& tt4, + wxWindow* item5, wxString& tt5 +) { + wxBoxSizer* rowSizer = new wxBoxSizer(wxHORIZONTAL); + + rowSizer->Add(item1, 0, wxALL, PAD1); + item1->SetToolTip(tt1); + rowSizer->Add(item2, 0, wxALL, PAD0); + item2->SetToolTip(tt2); + rowSizer->Add(item3, 0, wxALL, PAD1); + item3->SetToolTip(tt3); + rowSizer->Add(item4, 0, wxALL, PAD0); + item4->SetToolTip(tt4); + rowSizer->Add(item5, 0, wxALL, PAD1); + item5->SetToolTip(tt5); + + toSizer->Add(rowSizer, 0, 0, 1); +} + void CDlgAdvPreferencesBase::addNewRowToSizer( - wxSizer* toSizer, wxString& toolTipText, - wxWindow* first, wxWindow* second, wxWindow* third, - wxWindow* fourth, wxWindow* fifth) -{ - wxBoxSizer* rowSizer = new wxBoxSizer( wxHORIZONTAL ); + wxSizer* toSizer, wxString& toolTipText, + wxWindow* first, wxWindow* second, wxWindow* third, + wxWindow* fourth, wxWindow* fifth +) { + wxBoxSizer* rowSizer = new wxBoxSizer(wxHORIZONTAL); #ifdef __WXMSW__ // MSW adds space to the right of checkbox label if (first->IsKindOf(CLASSINFO(wxCheckBox))) { - rowSizer->Add(first, 0, wxTOP | wxBOTTOM |wxLEFT, 5 ); + rowSizer->Add(first, 0, wxTOP | wxBOTTOM |wxLEFT, PAD1 ); } else #endif - rowSizer->Add(first, 0, wxALL, 5 ); + rowSizer->Add(first, 0, wxALL, PAD1 ); + + // the last arg is padding. Less for text fields, to make things line up first->SetToolTip(toolTipText); - rowSizer->Add(second, 0, wxALL, 2 ); + rowSizer->Add(second, 0, wxALL, PAD0 ); second->SetToolTip(toolTipText); - rowSizer->Add(third, 0, wxALL, 5 ); + rowSizer->Add(third, 0, wxALL, PAD1); third->SetToolTip(toolTipText); if (fourth) { - rowSizer->Add(fourth, 0, wxALL, 2 ); + rowSizer->Add(fourth, 0, wxALL, PAD0); fourth->SetToolTip(toolTipText); } if (fifth) { - rowSizer->Add(fifth, 0, wxALL, 5 ); + rowSizer->Add(fifth, 0, wxALL, PAD1); fifth->SetToolTip(toolTipText); } toSizer->Add( rowSizer, 0, 0, 1 ); } - -wxPanel* CDlgAdvPreferencesBase::createProcessorTab(wxNotebook* notebook) -{ +wxPanel* CDlgAdvPreferencesBase::createProcessorTab(wxNotebook* notebook) { CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); wxASSERT(pSkinAdvanced); @@ -250,234 +279,336 @@ wxPanel* CDlgAdvPreferencesBase::createProcessorTab(wxNotebook* notebook) wxBoxSizer* processorTabSizer = new wxBoxSizer( wxVERTICAL ); - wxStaticBox* usageLimitsStaticBox = new wxStaticBox(processorTab, -1, _("Usage limits") ); - wxStaticBoxSizer* usageLimitsBoxSizer = new wxStaticBoxSizer(usageLimitsStaticBox, wxVERTICAL); - makeStaticBoxLabelItalic(usageLimitsStaticBox); - - /*xgettext:no-c-format*/ - wxString MaxCPUPctTT(_("Keep some CPUs free for other applications. Example: 75% means use 6 cores on an 8-core CPU.")); - wxStaticText* staticText20 = new wxStaticText( - usageLimitsStaticBox, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtProcUseProcessors = new wxTextCtrl( usageLimitsStaticBox, ID_TXTPROCUSEPROCESSORS, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - /*xgettext:no-c-format*/ - wxStaticText* staticText21 = new wxStaticText( usageLimitsStaticBox, ID_DEFAULT, _("% of the CPUs"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(usageLimitsBoxSizer, MaxCPUPctTT, staticText20, m_txtProcUseProcessors, staticText21); - - /*xgettext:no-c-format*/ - wxString MaxCPUTimeTT(_("Suspend/resume computing every few seconds to reduce CPU temperature and energy usage. Example: 75% means compute for 3 seconds, wait for 1 second, and repeat.")); - wxStaticText* staticText22 = new wxStaticText( - usageLimitsStaticBox, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtProcUseCPUTime = new wxTextCtrl( usageLimitsStaticBox, ID_TXTPROCUSECPUTIME, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - /*xgettext:no-c-format*/ - wxStaticText* staticText23 = new wxStaticText( usageLimitsStaticBox, ID_DEFAULT, _("% of CPU time"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(usageLimitsBoxSizer, MaxCPUTimeTT, staticText22, m_txtProcUseCPUTime, staticText23); - - processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - processorTabSizer->Add( usageLimitsBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); - - wxStaticBox* suspendComputingStaticBox = new wxStaticBox(processorTab, -1, _("When to suspend") ); - wxStaticBoxSizer* suspendComputingBoxSizer = new wxStaticBoxSizer(suspendComputingStaticBox, wxVERTICAL); - makeStaticBoxLabelItalic(suspendComputingStaticBox); + // ------------ In-use box -------------- + // + wxStaticBox* box = new wxStaticBox(processorTab, -1, _("When computer is in use") ); + wxStaticBoxSizer* box_sizer = new wxStaticBoxSizer(box, wxVERTICAL); + makeStaticBoxLabelItalic(box); - m_chkProcOnBatteries = new wxCheckBox( - suspendComputingStaticBox, ID_CHKPROCONBATTERIES, - _("Suspend when computer is on battery"), wxDefaultPosition, wxDefaultSize, 0 + // in-use if input in last X min + // + wxString ProcIdleForTT(_("This determines when the computer is considered 'in use'.")); + wxStaticText* staticText24 = new wxStaticText( + box, ID_DEFAULT, + // context: 'In use' means mouse or keyboard input in last ___ minutes + _("'In use' means mouse or keyboard input in last"), + wxDefaultPosition, wxDefaultSize, 0 ); - m_chkProcOnBatteries->SetToolTip( - _("Check this to suspend computing on portables when running on battery power.") + m_txtProcIdleFor = new wxTextCtrl( + box, ID_TXTPROCIDLEFOR, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT + ); + wxStaticText* staticText25 = new wxStaticText( + box, ID_DEFAULT, + // context: 'In use' means mouse or keyboard input in last ___ minutes + _("minutes"), + wxDefaultPosition, wxDefaultSize, 0 ); - suspendComputingBoxSizer->Add( m_chkProcOnBatteries, 0, wxALL, 5 ); + addNewRowToSizer(box_sizer, ProcIdleForTT, staticText24, m_txtProcIdleFor, staticText25); + // suspend while in use + // m_chkProcInUse = new wxCheckBox( - suspendComputingStaticBox, ID_CHKPROCINUSE, + box, ID_CHKPROCINUSE, _("Suspend when computer is in use"), wxDefaultPosition, wxDefaultSize, 0 ); m_chkProcInUse->SetToolTip( _("Check this to suspend computing and file transfers when you're using the computer.") ); - suspendComputingBoxSizer->Add( m_chkProcInUse, 0, wxALL, 5 ); + box_sizer->Add( m_chkProcInUse, 0, wxALL, 5 ); + // suspend GPU while in use + // m_chkGPUProcInUse = new wxCheckBox( - suspendComputingStaticBox, ID_CHKGPUPROCINUSE, + box, ID_CHKGPUPROCINUSE, _("Suspend GPU computing when computer is in use"), wxDefaultPosition, wxDefaultSize, 0 ); m_chkGPUProcInUse->SetToolTip( _("Check this to suspend GPU computing when you're using the computer.") ); - suspendComputingBoxSizer->Add( m_chkGPUProcInUse, 0, wxALL, 5 ); + box_sizer->Add( m_chkGPUProcInUse, 0, wxALL, 5 ); - // min idle time - wxString ProcIdleForTT(_("This determines when the computer is considered 'in use'.")); - - wxStaticText* staticText24 = new wxStaticText( - suspendComputingStaticBox, ID_DEFAULT, - // context: 'In use' means mouse/keyboard input in last ___ minutes - _("'In use' means mouse/keyboard input in last"), - wxDefaultPosition, wxDefaultSize, 0 - ); - - m_txtProcIdleFor = new wxTextCtrl( - suspendComputingStaticBox, ID_TXTPROCIDLEFOR, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT + // max # CPUs and throttling + // + wxStaticText* staticText20 = new wxStaticText( + box, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtProcUseProcessors = new wxTextCtrl(box, ID_TXTPROCUSEPROCESSORS, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + /*xgettext:no-c-format*/ + wxStaticText* staticText22 = new wxStaticText( + box, ID_DEFAULT, _("% of the CPUs and at most"), wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtProcUseCPUTime = new wxTextCtrl(box, ID_TXTPROCUSECPUTIME, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + /*xgettext:no-c-format*/ + wxStaticText* staticText23 = new wxStaticText(box, ID_DEFAULT, _("% of CPU time"), wxDefaultPosition, wxDefaultSize, 0 ); + /*xgettext:no-c-format*/ + wxString tt_ncpus(_("Keep some CPUs free for other applications. Example: 75% means use 6 cores on an 8-core CPU.")); + /*xgettext:no-c-format*/ + wxString tt_throttle(_("Suspend/resume computing every few seconds to reduce CPU temperature and energy usage. Example: 75% means compute for 3 seconds, wait for 1 second, and repeat.")); + add_row_to_sizer2(box_sizer, + staticText20, tt_ncpus, + m_txtProcUseProcessors, tt_ncpus, + staticText22, tt_ncpus, + m_txtProcUseCPUTime, tt_throttle, + staticText23, tt_throttle ); - wxStaticText* staticText25 = new wxStaticText( - suspendComputingStaticBox, ID_DEFAULT, - // context: 'In use' means mouse/keyboard input in last ___ minutes - _("minutes"), + // max CPU load + // + m_chkMaxLoad = new wxCheckBox( + box, ID_CHKMAXLOAD, + wxString(_("Suspend when non-BOINC CPU usage is above")), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtMaxLoad = new wxTextCtrl( + box, ID_TXTMAXLOAD, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("100.00")), wxTE_RIGHT + ); + wxString load_tt(_("Suspend computing when your computer is busy running other programs.")); + addNewRowToSizer(box_sizer, + load_tt, + m_chkMaxLoad, m_txtMaxLoad, + new wxStaticText(box, ID_DEFAULT, wxT("%"), wxDefaultPosition, wxDefaultSize, 0) + ); + + // max memory while in use + // + wxString MemoryMaxInUseTT = wxEmptyString; + MemoryMaxInUseTT.Printf(_("Limit the memory used by %s when you're using the computer."), pSkinAdvanced->GetApplicationShortName().c_str()); + wxStaticText* staticText50 = new wxStaticText(box, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 ); + textCtrlSize = getTextCtrlSize(wxT("100.00")); + m_txtMemoryMaxInUse = new wxTextCtrl( box, ID_TXTMEMORYMAXINUSE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + /*xgettext:no-c-format*/ + wxStaticText* staticText51 = new wxStaticText( box, ID_DEFAULT, _("% of memory"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, MemoryMaxInUseTT, staticText50, m_txtMemoryMaxInUse, staticText51); - addNewRowToSizer(suspendComputingBoxSizer, ProcIdleForTT, staticText24, m_txtProcIdleFor, staticText25); + processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); + processorTabSizer->Add(box_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); - // suspend after max idle time - wxString NoRecentInputTT(_("This allows some computers to enter low-power mode when not in use.")); + // ------------ Not-in-use box -------------- + // + + box = new wxStaticBox(processorTab, -1, _("When computer is not in use") ); + box_sizer = new wxStaticBoxSizer(box, wxVERTICAL); + makeStaticBoxLabelItalic(box); - wxStaticText* staticText27 = new wxStaticText( - suspendComputingStaticBox, ID_DEFAULT, - _("Suspend when no mouse/keyboard input in last"), + // max # CPUs and throttling + // + wxStaticText* staticText20niu = new wxStaticText( + box, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtProcUseProcessorsNotInUse = new wxTextCtrl(box, ID_TXTPROCUSEPROCESSORSNOTINUSE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT); + wxStaticText* staticText22niu = new wxStaticText( + /*xgettext:no-c-format*/ + box, ID_DEFAULT, _("% of the CPUs and at most"), wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtProcUseCPUTimeNotInUse = new wxTextCtrl(box, ID_TXTPROCUSECPUTIMENOTINUSE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT); + /*xgettext:no-c-format*/ + wxStaticText* staticText23niu = new wxStaticText(box, ID_DEFAULT, _("% of CPU time"), wxDefaultPosition, wxDefaultSize, 0); + add_row_to_sizer2(box_sizer, + staticText20niu, tt_ncpus, + m_txtProcUseProcessorsNotInUse, tt_ncpus, + staticText22niu, tt_ncpus, + m_txtProcUseCPUTimeNotInUse, tt_throttle, + staticText23niu, tt_throttle + ); + + // max CPU load + // + wxString MaxLoadCheckBoxTextniu = wxEmptyString; + MaxLoadCheckBoxTextniu.Printf(_("Suspend when non-BOINC CPU usage is above")); + m_chkMaxLoadNotInUse = new wxCheckBox( + box, ID_CHKMAXLOADNOTINUSE, MaxLoadCheckBoxTextniu, wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtMaxLoadNotInUse = new wxTextCtrl( + box, ID_TXTMAXLOADNOTINUSE, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("100.00")), wxTE_RIGHT + ); + wxStaticText* staticText26niu = new wxStaticText(box, ID_DEFAULT, wxT("%"), wxDefaultPosition, wxDefaultSize, 0 ); + wxString MaxLoadTTniu(_("Suspend computing when your computer is busy running other programs.")); + addNewRowToSizer(box_sizer, MaxLoadTTniu, m_chkMaxLoadNotInUse, m_txtMaxLoadNotInUse, staticText26niu); + + // max memory when not in use + // + wxString MemoryMaxOnIdleTT = wxEmptyString; + MemoryMaxOnIdleTT.Printf(_("Limit the memory used by %s when you're not using the computer."), pSkinAdvanced->GetApplicationShortName().c_str()); + wxStaticText* staticText52 = new wxStaticText( box, ID_DEFAULT, _("Use at most"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtMemoryMaxOnIdle = new wxTextCtrl( box, ID_TXTMEMORYMAXONIDLE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + /*xgettext:no-c-format*/ + wxStaticText* staticText53 = new wxStaticText( box, ID_DEFAULT, _("% of memory"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, MemoryMaxOnIdleTT, staticText52, m_txtMemoryMaxOnIdle, staticText53); + // suspend after idle time + // + wxString str0 = wxEmptyString; + str0.Printf(_("Suspend when no mouse or keyboard input in last")); + m_chkNoRecentInput = new wxCheckBox( + box, ID_CHKNORECENTINPUT, str0, wxDefaultPosition, wxDefaultSize, 0 + ); wxStaticText* staticText28 = new wxStaticText( - suspendComputingStaticBox, ID_DEFAULT, + box, ID_DEFAULT, _("minutes"), wxDefaultPosition, wxDefaultSize, 0 ); - m_txtNoRecentInput = new wxTextCtrl( - suspendComputingStaticBox, ID_TXTNORECENTINPUT, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT + box, ID_TXTNORECENTINPUT, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT ); + wxString NoRecentInputTT(_("This allows some computers to enter low-power mode when not in use.")); + addNewRowToSizer(box_sizer, NoRecentInputTT, m_chkNoRecentInput, m_txtNoRecentInput, staticText28); - addNewRowToSizer(suspendComputingBoxSizer, NoRecentInputTT, staticText27, m_txtNoRecentInput, staticText28); + processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); + processorTabSizer->Add(box_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE); - // max CPU load - wxString MaxLoadCheckBoxText = wxEmptyString; - MaxLoadCheckBoxText.Printf(_("Suspend when non-BOINC CPU usage is above")); + // ------------ General box -------------- + // - wxString MaxLoadTT(_("Suspend computing when your computer is busy running other programs.")); - m_chkMaxLoad = new wxCheckBox( - suspendComputingStaticBox, ID_CHKMAXLOAD, MaxLoadCheckBoxText, wxDefaultPosition, wxDefaultSize, 0); + box = new wxStaticBox(processorTab, -1, _("General")); + box_sizer = new wxStaticBoxSizer(box, wxVERTICAL); + makeStaticBoxLabelItalic(box); - m_txtMaxLoad = new wxTextCtrl( - suspendComputingStaticBox, ID_TXTMAXLOAD, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("100.00")), wxTE_RIGHT + // suspend while on battery + // + m_chkProcOnBatteries = new wxCheckBox( + box, ID_CHKPROCONBATTERIES, + _("Suspend when computer is on battery"), wxDefaultPosition, wxDefaultSize, 0 ); - - wxStaticText* staticText26 = new wxStaticText( suspendComputingStaticBox, ID_DEFAULT, wxT("%"), - wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(suspendComputingBoxSizer, MaxLoadTT, m_chkMaxLoad, m_txtMaxLoad, staticText26); - - suspendComputingBoxSizer->Add( - new wxStaticText( suspendComputingStaticBox, ID_DEFAULT, _("To suspend by time of day, see the \"Daily Schedules\" section."), wxDefaultPosition, wxDefaultSize, 0), - 0, wxALL, 5 + m_chkProcOnBatteries->SetToolTip( + _("Check this to suspend computing on portables when running on battery power.") ); + box_sizer->Add( m_chkProcOnBatteries, 0, wxALL, 5 ); - processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - processorTabSizer->Add( suspendComputingBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); + // switch every X + // + wxString ProcSwitchEveryTT = wxEmptyString; + ProcSwitchEveryTT.Printf(_("If you run several projects, %s may switch between them this often."), pSkinAdvanced->GetApplicationShortName().c_str()); + wxStaticText* staticText18 = new wxStaticText( + box, ID_DEFAULT, + // context: Switch between tasks every ___ minutes + _("Switch between tasks every"), + wxDefaultPosition, wxDefaultSize, 0 + ); + m_txtProcSwitchEvery = new wxTextCtrl( box, ID_TXTPROCSWITCHEVERY, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("9999.99")), wxTE_RIGHT ); + wxStaticText* staticText19 = new wxStaticText( + box, ID_DEFAULT, + // context: Switch between tasks every ___ minutes + _("minutes"), + wxDefaultPosition, wxDefaultSize, 0 + ); + addNewRowToSizer(box_sizer, ProcSwitchEveryTT, staticText18, m_txtProcSwitchEvery, staticText19); - wxStaticBox* miscProcStaticBox = new wxStaticBox( - processorTab, -1, - // Context: heading for a group of miscellaneous preferences - _("Other") + // checkpoint every X + // + wxString DiskWriteToDiskTT(_("This controls how often tasks save their state to disk, so that they later can be continued from that point.")); + wxStaticText* staticText46 = new wxStaticText( + box, ID_DEFAULT, + // context: Request tasks to checkpoint at most every ___ seconds + _("Request tasks to checkpoint at most every"), + wxDefaultPosition, wxDefaultSize, 0 ); - wxStaticBoxSizer* miscProcBoxSizer = new wxStaticBoxSizer( miscProcStaticBox, wxVERTICAL ); - makeStaticBoxLabelItalic(miscProcStaticBox); + m_txtDiskWriteToDisk = new wxTextCtrl( box, ID_TXTDISKWRITETODISK, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + wxStaticText* staticText47 = new wxStaticText( + box, ID_DEFAULT, + // context: Request tasks to checkpoint at most every ___ seconds + _("seconds"), + wxDefaultPosition, wxDefaultSize, 0 + ); + addNewRowToSizer(box_sizer, DiskWriteToDiskTT, staticText46, m_txtDiskWriteToDisk, staticText47); - // buffer sizes + // leave non-GPU tasks in memory while suspended +// + m_chkMemoryWhileSuspended = new wxCheckBox(box, ID_CHKMEMORYWHILESUSPENDED, _("Leave non-GPU tasks in memory while suspended"), wxDefaultPosition, wxDefaultSize, 0); + m_chkMemoryWhileSuspended->SetToolTip(_("If checked, suspended tasks stay in memory, and resume with no work lost. If unchecked, suspended tasks are removed from memory, and resume from their last checkpoint.")); + box_sizer->Add(m_chkMemoryWhileSuspended, 0, wxALL, 5); + +#if 0 + // work buffer min + // wxString NetConnectIntervalTT(_("Store at least enough tasks to keep the computer busy for this long.")); wxStaticText* staticText30 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, + box, ID_DEFAULT, // context: Store at least ___ days of work _("Store at least"), wxDefaultPosition, wxDefaultSize, 0 ); - m_txtNetConnectInterval = new wxTextCtrl( - miscProcStaticBox, ID_TXTNETCONNECTINTERVAL, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT + box, ID_TXTNETCONNECTINTERVAL, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - wxStaticText* staticText31 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, + box, ID_DEFAULT, // context: Store at least ___ days of work _("days of work"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, NetConnectIntervalTT, staticText30, m_txtNetConnectInterval, staticText31); - addNewRowToSizer(miscProcBoxSizer, NetConnectIntervalTT, staticText30, m_txtNetConnectInterval, staticText31); - + // work buffer additional + // wxString NetAdditionalDaysTT(_("Store additional tasks above the minimum level. Determines how much work is requested when contacting a project.")); wxStaticText* staticText331 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, + box, ID_DEFAULT, // context: Store up to an additional ___ days of work _("Store up to an additional"), wxDefaultPosition, wxDefaultSize, 0 ); staticText331->SetToolTip(NetAdditionalDaysTT); - m_txtNetAdditionalDays = new wxTextCtrl( - miscProcStaticBox, ID_TXTNETADDITIONALDAYS, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT + box, ID_TXTNETADDITIONALDAYS, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - wxStaticText* staticText341 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, + box, ID_DEFAULT, // context: Store up to an additional ___ days of work _("days of work"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(miscProcBoxSizer, NetAdditionalDaysTT, staticText331, m_txtNetAdditionalDays, staticText341); - - wxString ProcSwitchEveryTT = wxEmptyString; - ProcSwitchEveryTT.Printf(_("If you run several projects, %s may switch between them this often."), pSkinAdvanced->GetApplicationShortName().c_str()); - - wxStaticText* staticText18 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, - // context: Switch between tasks every ___ minutes - _("Switch between tasks every"), + addNewRowToSizer(box_sizer, NetAdditionalDaysTT, staticText331, m_txtNetAdditionalDays, staticText341); +#else + // work buffer + // + wxString tt_min(_("Store at least enough tasks to keep the computer busy for this long.")); + wxStaticText* staticText30 = new wxStaticText( + box, ID_DEFAULT, + // context: Store at least ___ days of work + _("Store at least"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtProcSwitchEvery = new wxTextCtrl( miscProcStaticBox, ID_TXTPROCSWITCHEVERY, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("9999.99")), wxTE_RIGHT ); - - wxStaticText* staticText19 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, - // context: Switch between tasks every ___ minutes - _("minutes"), - wxDefaultPosition, wxDefaultSize, 0 + m_txtNetConnectInterval = new wxTextCtrl( + box, ID_TXTNETCONNECTINTERVAL, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - addNewRowToSizer(miscProcBoxSizer, ProcSwitchEveryTT, staticText18, m_txtProcSwitchEvery, staticText19); - - wxString DiskWriteToDiskTT(_("This controls how often tasks save their state to disk, so that they later can be continued from that point.")); - wxStaticText* staticText46 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, - // context: Request tasks to checkpoint at most every ___ seconds - _("Request tasks to checkpoint at most every"), + wxStaticText* staticText31 = new wxStaticText( + box, ID_DEFAULT, + // context: Store at least ___ days of work + _("days and up to an additional"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtDiskWriteToDisk = new wxTextCtrl( miscProcStaticBox, ID_TXTDISKWRITETODISK, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - wxStaticText* staticText47 = new wxStaticText( - miscProcStaticBox, ID_DEFAULT, - // context: Request tasks to checkpoint at most every ___ seconds - _("seconds"), + wxString tt_extra(_("Store additional tasks above the minimum level. Determines how much work is requested when contacting a project.")); + m_txtNetAdditionalDays = new wxTextCtrl( + box, ID_TXTNETADDITIONALDAYS, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT + ); + wxStaticText* staticText341 = new wxStaticText( + box, ID_DEFAULT, + // context: Store up to an additional ___ days of work + _("days of work"), wxDefaultPosition, wxDefaultSize, 0 ); + add_row_to_sizer2(box_sizer, + staticText30, tt_min, + m_txtNetConnectInterval, tt_min, + staticText31, tt_min, + m_txtNetAdditionalDays, tt_extra, + staticText341, tt_extra + ); +#endif - addNewRowToSizer(miscProcBoxSizer, DiskWriteToDiskTT, staticText46, m_txtDiskWriteToDisk, staticText47); - - miscProcBoxSizer->AddSpacer(1); // Ensure staticText22 is fully visible on Mac +#if 0 + box_sizer->Add( + new wxStaticText(box, ID_DEFAULT, _("To suspend by time of day, see the \"Daily Schedules\" section."), wxDefaultPosition, wxDefaultSize, 0), + 0, wxALL, 5 + ); +#endif + box_sizer->AddSpacer(1); // Ensure staticText22 is fully visible on Mac - processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - processorTabSizer->Add( miscProcBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); - processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); + //processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); + processorTabSizer->Add( box_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); + //processorTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); processorTab->SetSizer( processorTabSizer ); processorTab->Layout(); @@ -486,9 +617,8 @@ wxPanel* CDlgAdvPreferencesBase::createProcessorTab(wxNotebook* notebook) return processorTab; } -wxPanel* CDlgAdvPreferencesBase::createNetworkTab(wxNotebook* notebook) -{ - CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); +wxPanel* CDlgAdvPreferencesBase::createNetworkTab(wxNotebook* notebook) { + CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); wxASSERT(pSkinAdvanced); wxSize textCtrlSize = getTextCtrlSize(wxT("9999.99")); @@ -498,54 +628,43 @@ wxPanel* CDlgAdvPreferencesBase::createNetworkTab(wxNotebook* notebook) wxBoxSizer* networkTabSizer = new wxBoxSizer( wxVERTICAL ); - wxStaticBox* networkUsageLimitsStaticBox = new wxStaticBox( networkTab, -1, _("Usage limits") ); - wxStaticBoxSizer* networkUsageLimitsBoxSizer = new wxStaticBoxSizer( networkUsageLimitsStaticBox, wxVERTICAL ); - makeStaticBoxLabelItalic(networkUsageLimitsStaticBox); - - // upload/download rates + wxStaticBox* box = new wxStaticBox( networkTab, -1, _("Network usage") ); + wxStaticBoxSizer* box_sizer = new wxStaticBoxSizer(box, wxVERTICAL); + makeStaticBoxLabelItalic(box); + // download rate + // wxString NetDownloadRateTT(_("Limit the download rate of file transfers.")); - m_chkNetDownloadRate = new wxCheckBox( networkUsageLimitsStaticBox, ID_CHKNETDOWNLOADRATE, _("Limit download rate to"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtNetDownloadRate = new wxTextCtrl( networkUsageLimitsStaticBox, ID_TXTNETDOWNLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - wxStaticText* staticText33 = new wxStaticText( networkUsageLimitsStaticBox, ID_DEFAULT, _("KB/second"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(networkUsageLimitsBoxSizer, NetDownloadRateTT, m_chkNetDownloadRate, m_txtNetDownloadRate, staticText33); + m_chkNetDownloadRate = new wxCheckBox( box, ID_CHKNETDOWNLOADRATE, _("Limit download rate to"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtNetDownloadRate = new wxTextCtrl( box, ID_TXTNETDOWNLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + wxStaticText* staticText33 = new wxStaticText( box, ID_DEFAULT, _("KB/second"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, NetDownloadRateTT, m_chkNetDownloadRate, m_txtNetDownloadRate, staticText33); + // upload rate + // wxString NetUploadRateTT(_("Limit the upload rate of file transfers.")); - m_chkNetUploadRate = new wxCheckBox( networkUsageLimitsStaticBox, ID_CHKNETUPLOADRATE, _("Limit upload rate to"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtNetUploadRate = new wxTextCtrl( networkUsageLimitsStaticBox, ID_TXTNETUPLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - wxStaticText* staticText35 = new wxStaticText( networkUsageLimitsStaticBox, ID_DEFAULT, _("KB/second"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(networkUsageLimitsBoxSizer, NetUploadRateTT, m_chkNetUploadRate, m_txtNetUploadRate, staticText35); + m_chkNetUploadRate = new wxCheckBox( box, ID_CHKNETUPLOADRATE, _("Limit upload rate to"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtNetUploadRate = new wxTextCtrl( box, ID_TXTNETUPLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + wxStaticText* staticText35 = new wxStaticText( box, ID_DEFAULT, _("KB/second"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, NetUploadRateTT, m_chkNetUploadRate, m_txtNetUploadRate, staticText35); // long-term quota - + // wxString daily_xfer_limitTT = wxEmptyString; daily_xfer_limitTT.Printf(_("Example: %s should transfer at most 2000 MB of data every 30 days."), pSkinAdvanced->GetApplicationShortName().c_str()); - - m_chk_daily_xfer_limit = new wxCheckBox( networkUsageLimitsStaticBox, ID_CHKDAILYXFERLIMIT, _("Limit usage to"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txt_daily_xfer_limit_mb = new wxTextCtrl( networkUsageLimitsStaticBox, ID_TXTNETDOWNLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - wxStaticText* staticText_daily_xfer2 = new wxStaticText( networkUsageLimitsStaticBox, ID_DEFAULT, _("MB every"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txt_daily_xfer_period_days = new wxTextCtrl( networkUsageLimitsStaticBox, ID_TXTNETUPLOADRATE, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT ); - - wxStaticText* staticText_daily_xfer4 = new wxStaticText( networkUsageLimitsStaticBox, ID_DEFAULT, _("days"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(networkUsageLimitsBoxSizer, daily_xfer_limitTT, m_chk_daily_xfer_limit, m_txt_daily_xfer_limit_mb, staticText_daily_xfer2, m_txt_daily_xfer_period_days, staticText_daily_xfer4); - - networkUsageLimitsBoxSizer->Add( - new wxStaticText( networkUsageLimitsStaticBox, ID_DEFAULT, _("To limit transfers by time of day, see the \"Daily Schedules\" section."), wxDefaultPosition, wxDefaultSize, 0), + m_chk_daily_xfer_limit = new wxCheckBox( box, ID_CHKDAILYXFERLIMIT, _("Limit usage to"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txt_daily_xfer_limit_mb = new wxTextCtrl( box, ID_TXTNETDOWNLOADRATE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); + wxStaticText* staticText_daily_xfer2 = new wxStaticText( box, ID_DEFAULT, _("MB every"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txt_daily_xfer_period_days = new wxTextCtrl( box, ID_TXTNETUPLOADRATE, wxEmptyString, wxDefaultPosition, getTextCtrlSize(wxT("999.99")), wxTE_RIGHT ); + wxStaticText* staticText_daily_xfer4 = new wxStaticText( box, ID_DEFAULT, _("days"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(box_sizer, daily_xfer_limitTT, m_chk_daily_xfer_limit, m_txt_daily_xfer_limit_mb, staticText_daily_xfer2, m_txt_daily_xfer_period_days, staticText_daily_xfer4); + box_sizer->Add( + new wxStaticText( box, ID_DEFAULT, _("To limit transfers by time of day, see the \"Daily Schedules\" section."), wxDefaultPosition, wxDefaultSize, 0), 0, wxALL, 5 ); networkTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - networkTabSizer->Add( networkUsageLimitsBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); + networkTabSizer->Add( box_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); // Context: heading for a group of miscellaneous preferences wxStaticBox* connectOptionsStaticBox = new wxStaticBox( @@ -556,17 +675,21 @@ wxPanel* CDlgAdvPreferencesBase::createNetworkTab(wxNotebook* notebook) wxStaticBoxSizer* connectOptionsSizer = new wxStaticBoxSizer( connectOptionsStaticBox, wxVERTICAL ); makeStaticBoxLabelItalic(connectOptionsStaticBox); + // skip image verification + // wxString NetSkipImageVerificationTT = wxEmptyString; NetSkipImageVerificationTT.Printf(_("Check this only if your Internet provider modifies image files. Skipping verification reduces the security of %s."), pSkinAdvanced->GetApplicationShortName().c_str()); - m_chkNetSkipImageVerification = new wxCheckBox( connectOptionsStaticBox, ID_CHKNETSKIPIMAGEVERIFICATION, _("Skip data verification for image files"), wxDefaultPosition, wxDefaultSize, 0 ); m_chkNetSkipImageVerification->SetToolTip(NetSkipImageVerificationTT); connectOptionsSizer->Add( m_chkNetSkipImageVerification, 0, wxALL, 5 ); + // confirm before connecting + // m_chkNetConfirmBeforeConnect = new wxCheckBox( connectOptionsStaticBox, ID_CHKNETCONFIRMBEFORECONNECT, _("Confirm before connecting to Internet"), wxDefaultPosition, wxDefaultSize, 0 ); m_chkNetConfirmBeforeConnect->SetToolTip( _("Useful only if you have a modem, ISDN or VPN connection.") ); connectOptionsSizer->Add( m_chkNetConfirmBeforeConnect, 0, wxALL, 5 ); + // disconnect when done m_chkNetDisconnectWhenDone = new wxCheckBox( connectOptionsStaticBox, ID_CHKNETDISCONNECTWHENDONE, _("Disconnect when done"), wxDefaultPosition, wxDefaultSize, 0 ); m_chkNetDisconnectWhenDone->SetToolTip( _("Useful only if you have a modem, ISDN or VPN connection.") ); connectOptionsSizer->Add( m_chkNetDisconnectWhenDone, 0, wxALL, 5 ); @@ -582,8 +705,7 @@ wxPanel* CDlgAdvPreferencesBase::createNetworkTab(wxNotebook* notebook) return networkTab; } -wxPanel* CDlgAdvPreferencesBase::createDiskAndMemoryTab(wxNotebook* notebook) -{ +wxPanel* CDlgAdvPreferencesBase::createDiskTab(wxNotebook* notebook) { CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced(); wxASSERT(pSkinAdvanced); @@ -592,110 +714,65 @@ wxPanel* CDlgAdvPreferencesBase::createDiskAndMemoryTab(wxNotebook* notebook) wxPanel* diskMemoryTab = new wxPanel( notebook, ID_TABPAGE_DISK, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); diskMemoryTab->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); - wxBoxSizer* diskAndMemoryTabSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* diskTabSizer = new wxBoxSizer( wxVERTICAL ); - wxStaticBox* diskUsageStaticBox = new wxStaticBox( diskMemoryTab, -1, _("Disk") ); + wxStaticBox* diskUsageStaticBox = new wxStaticBox( diskMemoryTab, -1, _("Disk usage") ); wxStaticBoxSizer* diskUsageBoxSizer = new wxStaticBoxSizer( diskUsageStaticBox, wxVERTICAL ); makeStaticBoxLabelItalic(diskUsageStaticBox); - wxString MostRestrictiveText = wxEmptyString; - MostRestrictiveText.Printf(_("%s will use the most restrictive of these settings:"), pSkinAdvanced->GetApplicationShortName().c_str()); - diskUsageBoxSizer->Add(new wxStaticText( diskUsageStaticBox, -1, MostRestrictiveText, wxDefaultPosition, wxDefaultSize, 0), - 0, wxALL, 5 - ); - + // total disk usage + // wxString DiskMaxSpaceTT = wxEmptyString; DiskMaxSpaceTT.Printf(_("Limit the total amount of disk space used by %s."), pSkinAdvanced->GetApplicationShortName().c_str()); - m_chkDiskMaxSpace = new wxCheckBox ( diskUsageStaticBox, ID_CHKDISKMAXSPACE, _("Use no more than"), wxDefaultPosition, wxDefaultSize, 0 ); - m_txtDiskMaxSpace = new wxTextCtrl( diskUsageStaticBox, ID_TXTDISKMAXSPACE,wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - wxStaticText* staticText41 = new wxStaticText( diskUsageStaticBox, ID_DEFAULT, _("GB"), wxDefaultPosition, wxDefaultSize, 0 ); - addNewRowToSizer(diskUsageBoxSizer, DiskMaxSpaceTT, m_chkDiskMaxSpace, m_txtDiskMaxSpace, staticText41); + // leave at least X free + // wxString DiskLeastFreeTT = wxEmptyString; DiskLeastFreeTT.Printf(_("Limit disk usage to leave this much free space on the volume where %s stores data."), pSkinAdvanced->GetApplicationShortName().c_str()); - m_chkDiskLeastFree = new wxCheckBox ( diskUsageStaticBox, ID_CHKDISKLEASTFREE, _("Leave at least"), wxDefaultPosition, wxDefaultSize, 0 ); - m_txtDiskLeastFree = new wxTextCtrl( diskUsageStaticBox, ID_TXTDISKLEASTFREE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - wxStaticText* staticText43 = new wxStaticText( diskUsageStaticBox, ID_DEFAULT, _("GB free"), wxDefaultPosition, wxDefaultSize, 0 ); - addNewRowToSizer(diskUsageBoxSizer, DiskLeastFreeTT, m_chkDiskLeastFree, m_txtDiskLeastFree, staticText43); + // use at most X% + // wxString DiskMaxOfTotalTT = wxEmptyString; DiskMaxOfTotalTT.Printf(_("Limit the percentage of disk space used by %s on the volume where it stores data."), pSkinAdvanced->GetApplicationShortName().c_str()); - m_chkDiskMaxOfTotal = new wxCheckBox ( diskUsageStaticBox, ID_CHKDISKMAXOFTOTAL, _("Use no more than"), wxDefaultPosition, wxDefaultSize, 0 ); - m_txtDiskMaxOfTotal = new wxTextCtrl( diskUsageStaticBox, ID_TXTDISKMAXOFTOTAL, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - /*xgettext:no-c-format*/ wxStaticText* staticText45 = new wxStaticText( diskUsageStaticBox, ID_DEFAULT, _("% of total"), wxDefaultPosition, wxDefaultSize, 0 ); - addNewRowToSizer(diskUsageBoxSizer, DiskMaxOfTotalTT, m_chkDiskMaxOfTotal, m_txtDiskMaxOfTotal, staticText45); - diskAndMemoryTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - diskAndMemoryTabSizer->Add( diskUsageBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); - - wxStaticBox* memoryUsageStaticBox = new wxStaticBox( diskMemoryTab, -1, _("Memory") ); - wxStaticBoxSizer* memoryUsageBoxSizer = new wxStaticBoxSizer( memoryUsageStaticBox, wxVERTICAL ); - makeStaticBoxLabelItalic(memoryUsageStaticBox); - - wxString MemoryMaxInUseTT = wxEmptyString; - MemoryMaxInUseTT.Printf(_("Limit the memory used by %s when you're using the computer."), pSkinAdvanced->GetApplicationShortName().c_str()); - - wxStaticText* staticText50 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("When computer is in use, use at most"), wxDefaultPosition, wxDefaultSize, 0 ); - - textCtrlSize = getTextCtrlSize(wxT("100.00")); - m_txtMemoryMaxInUse = new wxTextCtrl( memoryUsageStaticBox, ID_TXTMEMORYMAXINUSE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - /*xgettext:no-c-format*/ - wxStaticText* staticText51 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("%"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(memoryUsageBoxSizer, MemoryMaxInUseTT, staticText50, m_txtMemoryMaxInUse, staticText51); - - wxString MemoryMaxOnIdleTT = wxEmptyString; - MemoryMaxOnIdleTT.Printf(_("Limit the memory used by %s when you're not using the computer."), pSkinAdvanced->GetApplicationShortName().c_str()); - - wxStaticText* staticText52 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("When computer is not in use, use at most"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtMemoryMaxOnIdle = new wxTextCtrl( memoryUsageStaticBox, ID_TXTMEMORYMAXONIDLE, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - - /*xgettext:no-c-format*/ - wxStaticText* staticText53 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("%"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(memoryUsageBoxSizer, MemoryMaxOnIdleTT, staticText52, m_txtMemoryMaxOnIdle, staticText53); - - m_chkMemoryWhileSuspended = new wxCheckBox( memoryUsageStaticBox, ID_CHKMEMORYWHILESUSPENDED, _("Leave non-GPU tasks in memory while suspended"), wxDefaultPosition, wxDefaultSize, 0 ); - m_chkMemoryWhileSuspended->SetToolTip( _("If checked, suspended tasks stay in memory, and resume with no work lost. If unchecked, suspended tasks are removed from memory, and resume from their last checkpoint.") ); - memoryUsageBoxSizer->Add(m_chkMemoryWhileSuspended, 0, wxALL, 5 ); - + wxString MostRestrictiveText = wxEmptyString; + MostRestrictiveText.Printf(_("%s will use the most restrictive of the above settings"), pSkinAdvanced->GetApplicationShortName().c_str()); + diskUsageBoxSizer->Add(new wxStaticText(diskUsageStaticBox, -1, MostRestrictiveText, wxDefaultPosition, wxDefaultSize, 0), + 0, wxALL, 5 + ); + + // swap space limit + // wxString DiskMaxSwapTT = wxEmptyString; DiskMaxSwapTT.Printf(_("Limit the swap space (page file) used by %s."), pSkinAdvanced->GetApplicationShortName().c_str()); - - wxStaticText* staticText48 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("Page/swap file: use at most"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_txtDiskMaxSwap = new wxTextCtrl( memoryUsageStaticBox, ID_TXTDISKWRITETODISK, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); - + wxStaticText* staticText48 = new wxStaticText(diskUsageStaticBox, ID_DEFAULT, _("Page/swap file: use at most"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtDiskMaxSwap = new wxTextCtrl(diskUsageStaticBox, ID_TXTDISKWRITETODISK, wxEmptyString, wxDefaultPosition, textCtrlSize, wxTE_RIGHT ); /*xgettext:no-c-format*/ - wxStaticText* staticText49 = new wxStaticText( memoryUsageStaticBox, ID_DEFAULT, _("%"), wxDefaultPosition, wxDefaultSize, 0 ); - - addNewRowToSizer(memoryUsageBoxSizer, DiskMaxSwapTT, staticText48, m_txtDiskMaxSwap, staticText49); + wxStaticText* staticText49 = new wxStaticText(diskUsageStaticBox, ID_DEFAULT, _("%"), wxDefaultPosition, wxDefaultSize, 0 ); + addNewRowToSizer(diskUsageBoxSizer, DiskMaxSwapTT, staticText48, m_txtDiskMaxSwap, staticText49); - diskAndMemoryTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); - diskAndMemoryTabSizer->Add( memoryUsageBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE ); - diskAndMemoryTabSizer->AddSpacer( STATICBOXVERTICALSPACER ); + diskTabSizer->AddSpacer(STATICBOXVERTICALSPACER); + diskTabSizer->Add(diskUsageBoxSizer, 0, wxLEFT | wxRIGHT | wxEXPAND, STATICBOXBORDERSIZE); - diskMemoryTab->SetSizer( diskAndMemoryTabSizer ); + diskMemoryTab->SetSizer( diskTabSizer ); diskMemoryTab->Layout(); - diskAndMemoryTabSizer->Fit( diskMemoryTab ); + diskTabSizer->Fit( diskMemoryTab ); return diskMemoryTab; } diff --git a/clientgui/DlgAdvPreferencesBase.h b/clientgui/DlgAdvPreferencesBase.h index 416bde5cd9a..94d3bc3be97 100644 --- a/clientgui/DlgAdvPreferencesBase.h +++ b/clientgui/DlgAdvPreferencesBase.h @@ -39,9 +39,6 @@ #include #include -/////////////////////////////////////////////////////////////////////////// - - #define PROC_DAY_OF_WEEK_TOOLTIP_TEXT _("On this day of the week, compute only during these hours.") #define NET_DAY_OF_WEEK_TOOLTIP_TEXT _("On this day of the week, transfer files only during these hours.") @@ -81,6 +78,7 @@ enum { ID_CHKPROCEVERYDAY, ID_CHKPROCINUSE, ID_CHKMAXLOAD, + ID_CHKMAXLOADNOTINUSE, ID_CHKPROCONBATTERIES, ID_TABPAGE_SCHED, ID_TABPAGE_DISK, @@ -113,6 +111,7 @@ enum { ID_TXTNETWEDNESDAYSTART, ID_TXTNETWEDNESDAYSTOP, ID_TXTPROCUSECPUTIME, + ID_TXTPROCUSECPUTIMENOTINUSE, ID_TXTPROCEVERYDAYSTART, ID_TXTPROCEVERYDAYSTOP, ID_TXTPROCFRIDAYSTART, @@ -131,36 +130,84 @@ enum { ID_TXTPROCTUESDAYSTART, ID_TXTPROCTUESDAYSTOP, ID_TXTPROCUSEPROCESSORS, + ID_TXTPROCUSEPROCESSORSNOTINUSE, ID_TXTPROCWEDNESDAYSTART, ID_TXTPROCWEDNESDAYSTOP, ID_CHKGPUPROCINUSE, + ID_CHKNORECENTINPUT, ID_TXTMAXLOAD, + ID_TXTMAXLOADNOTINUSE, ID_DAILY_XFER_LIMIT_MB, ID_DAILY_XFER_PERIOD_DAYS, ID_ADV_PREFS_LAST }; - -/** - * Class CDlgAdvPreferencesBase - */ -class CDlgAdvPreferencesBase : public wxDialog -{ +class CDlgAdvPreferencesBase : public wxDialog { protected: wxStaticBitmap* m_bmpWarning; wxButton* m_btnClear; wxPanel* m_panelControls; wxNotebook* m_Notebook; + + // Computing panel + // + // In-use items wxPanel* m_panelProcessor; - wxTextCtrl* m_txtProcUseProcessors; - wxTextCtrl* m_txtProcUseCPUTime; - wxCheckBox* m_chkProcOnBatteries; + wxTextCtrl* m_txtProcIdleFor; wxCheckBox* m_chkProcInUse; wxCheckBox* m_chkGPUProcInUse; - wxTextCtrl* m_txtProcIdleFor; - wxTextCtrl* m_txtNoRecentInput; + wxTextCtrl* m_txtProcUseProcessors; + wxTextCtrl* m_txtProcUseCPUTime; wxCheckBox* m_chkMaxLoad; wxTextCtrl* m_txtMaxLoad; + wxTextCtrl* m_txtMemoryMaxInUse; + // Not in Use items + // + wxTextCtrl* m_txtProcUseProcessorsNotInUse; + wxTextCtrl* m_txtProcUseCPUTimeNotInUse; + wxCheckBox* m_chkMaxLoadNotInUse; + wxTextCtrl* m_txtMaxLoadNotInUse; + wxTextCtrl* m_txtMemoryMaxOnIdle; + wxCheckBox* m_chkNoRecentInput; + wxTextCtrl* m_txtNoRecentInput; + // General items + // + wxCheckBox* m_chkProcOnBatteries; + wxTextCtrl* m_txtProcSwitchEvery; + wxTextCtrl* m_txtDiskWriteToDisk; + wxCheckBox* m_chkMemoryWhileSuspended; + wxTextCtrl* m_txtNetConnectInterval; + wxTextCtrl* m_txtNetAdditionalDays; + wxTextCtrl* m_txtDiskMaxSwap; + + // Network panel + // + wxPanel* m_panelNetwork; + wxCheckBox* m_chkNetDownloadRate; + wxTextCtrl* m_txtNetDownloadRate; + wxCheckBox* m_chkNetUploadRate; + wxTextCtrl* m_txtNetUploadRate; + + wxCheckBox* m_chk_daily_xfer_limit; + wxTextCtrl* m_txt_daily_xfer_limit_mb; + wxTextCtrl* m_txt_daily_xfer_period_days; + + wxCheckBox* m_chkNetSkipImageVerification; + wxCheckBox* m_chkNetConfirmBeforeConnect; + wxCheckBox* m_chkNetDisconnectWhenDone; + + // Disk panel + // + wxPanel* m_panelDisk; + wxCheckBox* m_chkDiskMaxSpace; + wxTextCtrl* m_txtDiskMaxSpace; + wxCheckBox* m_chkDiskLeastFree; + wxTextCtrl* m_txtDiskLeastFree; + wxCheckBox* m_chkDiskMaxOfTotal; + wxTextCtrl* m_txtDiskMaxOfTotal; + + // Daily schedules panel + wxPanel* m_panelDailySchedules; wxCheckBox* m_chkNetEveryDay; wxCheckBox* m_chkProcEveryDay; wxTextCtrl* m_txtProcEveryDayStart; @@ -186,23 +233,7 @@ class CDlgAdvPreferencesBase : public wxDialog wxCheckBox* m_chkProcSunday; wxTextCtrl* m_txtProcSundayStart; wxTextCtrl* m_txtProcSundayStop; - wxTextCtrl* m_txtProcSwitchEvery; - wxTextCtrl* m_txtDiskWriteToDisk; - wxPanel* m_panelNetwork; - wxCheckBox* m_chkNetDownloadRate; - wxTextCtrl* m_txtNetDownloadRate; - wxCheckBox* m_chkNetUploadRate; - wxTextCtrl* m_txtNetUploadRate; - wxCheckBox * m_chk_daily_xfer_limit; - wxTextCtrl* m_txt_daily_xfer_limit_mb; - wxTextCtrl* m_txt_daily_xfer_period_days; - - wxTextCtrl* m_txtNetConnectInterval; - wxTextCtrl* m_txtNetAdditionalDays; - wxCheckBox* m_chkNetSkipImageVerification; - wxCheckBox* m_chkNetConfirmBeforeConnect; - wxCheckBox* m_chkNetDisconnectWhenDone; wxTextCtrl* m_txtNetEveryDayStart; wxTextCtrl* m_txtNetEveryDayStop; wxCheckBox* m_chkNetMonday; @@ -226,18 +257,6 @@ class CDlgAdvPreferencesBase : public wxDialog wxCheckBox* m_chkNetSunday; wxTextCtrl* m_txtNetSundayStart; wxTextCtrl* m_txtNetSundayStop; - wxPanel* m_panelDiskAndMemory; - wxCheckBox* m_chkDiskMaxSpace; - wxTextCtrl* m_txtDiskMaxSpace; - wxCheckBox* m_chkDiskLeastFree; - wxTextCtrl* m_txtDiskLeastFree; - wxCheckBox* m_chkDiskMaxOfTotal; - wxTextCtrl* m_txtDiskMaxOfTotal; - wxTextCtrl* m_txtDiskMaxSwap; - wxTextCtrl* m_txtMemoryMaxInUse; - wxTextCtrl* m_txtMemoryMaxOnIdle; - wxCheckBox* m_chkMemoryWhileSuspended; - wxPanel* m_panelDailySchedules; wxPanel* m_panelButtons; wxButton* m_btnOK; @@ -248,15 +267,27 @@ class CDlgAdvPreferencesBase : public wxDialog bool m_bUsingLocalPrefs; public: - CDlgAdvPreferencesBase( wxWindow* parent, int id = -1, wxString title = wxT(""), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxDEFAULT_DIALOG_STYLE ); + CDlgAdvPreferencesBase( + wxWindow* parent, int id = -1, wxString title = wxT(""), wxPoint pos = wxDefaultPosition, + wxSize size = wxDefaultSize, int style = wxDEFAULT_DIALOG_STYLE + ); private: void addNewRowToSizer(wxSizer* toSizer, wxString& toolTipText, - wxWindow* first, wxWindow* second, wxWindow* third, - wxWindow* fourth=NULL, wxWindow* fifth=NULL); + wxWindow* first, wxWindow* second, wxWindow* third, + wxWindow* fourth=NULL, wxWindow* fifth=NULL + ); + // variant with separate tooltip per item + void add_row_to_sizer2(wxSizer* toSizer, + wxWindow* item1, wxString& tt1, + wxWindow* item2, wxString& tt2, + wxWindow* item3, wxString& tt3, + wxWindow* item4, wxString& tt4, + wxWindow* item5, wxString& tt5 + ); wxPanel* createProcessorTab(wxNotebook* notebook); wxPanel* createNetworkTab(wxNotebook* notebook); - wxPanel* createDiskAndMemoryTab(wxNotebook* notebook); + wxPanel* createDiskTab(wxNotebook* notebook); wxPanel* createDailySchedulesTab(wxNotebook* notebook); wxSize getTextCtrlSize(wxString maxText); bool doesLocalPrefsFileExist(); diff --git a/html/inc/prefs.inc b/html/inc/prefs.inc index 2b3021aa987..c059b8ee76e 100644 --- a/html/inc/prefs.inc +++ b/html/inc/prefs.inc @@ -1,7 +1,7 @@ Requires BOINC 7.20.3+", + // xgettext:no-php-format + tra("Keep some CPUs free for other applications. Example: 75% means use 6 cores on an 8-core CPU."), + "niu_max_ncpus_pct", + // xgettext:no-php-format + new NUM_SPEC(tra("% of the CPUs"), 1, 100, 0) ), new PREF_NUM( - tra("'In use' means mouse/keyboard input in last"), - tra("This determines when the computer is considered 'in use'."), - "idle_time_to_run", - new NUM_SPEC(tra("minutes"), 1, 9999, 3), - true + tra("Use at most") ."
Requires BOINC 7.20.3+", + // xgettext:no-php-format + tra("Suspend/resume computing every few seconds to reduce CPU temperature and energy usage. Example: 75% means compute for 3 seconds, wait for 1 second, and repeat."), + "niu_cpu_usage_limit", + // xgettext:no-php-format + new NUM_SPEC(tra("% of CPU time"), 1, 100, 0) + ), + new PREF_OPT_NUM( + tra("Suspend when non-BOINC CPU usage is above")."
Requires BOINC 7.20.3+", + tra("Suspend computing when your computer is busy running other programs."), + "niu_suspend_cpu_usage", + new NUM_SPEC("%", 0, 100, 0) + ), + new PREF_NUM( + tra("Use at most"), + tra("Limit the memory used by BOINC when you're not using the computer."), + "ram_max_used_idle_pct", + // xgettext:no-php-format + new NUM_SPEC(tra("% of memory"), 1, 100, 90) ), new PREF_OPT_NUM( tra("Suspend when no mouse/keyboard input in last"), @@ -97,18 +134,32 @@ $cpu_prefs = array( "suspend_if_no_recent_input", new NUM_SPEC(tra("minutes"), 0, 9999, 0, 1, 60) ), - new PREF_OPT_NUM( - tra("Suspend when non-BOINC CPU usage is above"), - tra("Suspend computing when your computer is busy running other programs."), - "suspend_cpu_usage", - new NUM_SPEC("%", 0, 100, 25) +]; +$job_prefs = [ + new PREF_BOOL( + tra("Suspend when computer is on battery"), + tra("Check this to suspend computing on portables when running on battery power."), + "run_on_batteries", + false, true ), - new PREF_HOUR_RANGE( - tra("Compute only between"), - tra("Compute only during a particular period each day."), - "start_hour", "end_hour" + new PREF_NUM( + tra("Switch between tasks every"), + tra("If you run several projects, BOINC may switch between them this often."), + "cpu_scheduling_period_minutes", + new NUM_SPEC(tra("minutes"), 1, 9999, 60) + ), + new PREF_NUM( + tra("Request tasks to checkpoint at most every"), + tra("This controls how often tasks save their state to disk, so that later they can be continued from that point."), + "disk_interval", + new NUM_SPEC(tra("seconds"), 0, 9999999, 60) + ), + new PREF_BOOL( + tra("Leave non-GPU tasks in memory while suspended"), + tra("If checked, suspended tasks stay in memory, and resume with no work lost. If unchecked, suspended tasks are removed from memory, and resume from their last checkpoint."), + "leave_apps_in_memory", + false ), - tra("Other"), new PREF_NUM( tra("Store at least"), tra("Store at least enough tasks to keep the computer busy for this long."), @@ -121,19 +172,12 @@ $cpu_prefs = array( "work_buf_additional_days", new NUM_SPEC(tra("days of work"), 0, 10, .5) ), - new PREF_NUM( - tra("Switch between tasks every"), - tra("If you run several projects, BOINC may switch between them this often."), - "cpu_scheduling_period_minutes", - new NUM_SPEC(tra("minutes"), 1, 9999, 60) - ), - new PREF_NUM( - tra("Request tasks to checkpoint at most every"), - tra("This controls how often tasks save their state to disk, so that later they can be continued from that point."), - "disk_interval", - new NUM_SPEC(tra("seconds"), 0, 9999999, 60) + new PREF_HOUR_RANGE( + tra("Compute only between"), + tra("Compute only during a particular period each day."), + "start_hour", "end_hour" ), -); +]; $dp = get_disk_space_config(); @@ -157,29 +201,6 @@ $disk_prefs = array( // xgettext:no-php-format new NUM_SPEC(tra("% of total"), 0, 100, $dp->disk_max_used_pct) ), -); - -$mem_prefs = array( - new PREF_NUM( - tra("When computer is in use, use at most"), - tra("Limit the memory used by BOINC when you're using the computer."), - "ram_max_used_busy_pct", - // xgettext:no-php-format - new NUM_SPEC(tra("%"), 1, 100, 50) - ), - new PREF_NUM( - tra("When computer is not in use, use at most"), - tra("Limit the memory used by BOINC when you're not using the computer."), - "ram_max_used_idle_pct", - // xgettext:no-php-format - new NUM_SPEC(tra("%"), 1, 100, 90) - ), - new PREF_BOOL( - tra("Leave non-GPU tasks in memory while suspended"), - tra("If checked, suspended tasks stay in memory, and resume with no work lost. If unchecked, suspended tasks are removed from memory, and resume from their last checkpoint."), - "leave_apps_in_memory", - false - ), new PREF_NUM( tra("Page/swap file: use at most"), tra("Limit the swap space (page file) used by BOINC."), @@ -190,7 +211,6 @@ $mem_prefs = array( ); $net_prefs = array( - tra("Usage limits"), new PREF_OPT_NUM( tra("Limit download rate to"), tra("Limit the download rate of file transfers."), @@ -211,13 +231,11 @@ $net_prefs = array( new NUM_SPEC(tra("MB every"), 0, 9999999, 0, 1, 10000), new NUM_SPEC(tra("days"), 0, 9999999, 0, 1, 30) ), - tra("When to suspend"), new PREF_HOUR_RANGE( tra("Transfer files only between"), tra("Transfer files only during a particular period each day."), "net_start_hour", "net_end_hour" ), - tra("Other"), new PREF_BOOL( tra("Skip data verification for image files"), tra("Check this only if your Internet provider modifies image files. Skipping verification reduces the security of BOINC."), @@ -238,10 +256,11 @@ $net_prefs = array( ), ); -define("CPU_LIMIT_DESC", tra("Computing")); -define("DISK_LIMIT_DESC", tra("Disk")); -define("MEM_LIMIT_DESC", tra("Memory")); -define("NETWORK_LIMIT_DESC", tra("Network")); +define("IN_USE_DESC", tra("When computer is in use")); +define("NOT_IN_USE_DESC", tra("When computer is not in use")); +define("JOBS_DESC", tra("General")); +define("DISK_DESC", tra("Disk")); +define("NET_DESC", tra("Network")); // These texts are used in multiple places in prefs_edit.php and add_venue.php define("PREFS_FORM_DESC1", tra("These preferences apply to all the BOINC projects in which you participate.")."

"); @@ -323,29 +342,33 @@ function element_end_global($parser, $name) { global $parse_result; global $top_parse_result; global $venue_name; - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; - foreach ($cpu_prefs as $p) { - if (is_string($p)) continue; + foreach ($in_use_prefs as $p) { if ($p->xml_parse($parse_result, $name, $text)) { return; } } - foreach ($disk_prefs as $p) { + foreach ($not_in_use_prefs as $p) { if ($p->xml_parse($parse_result, $name, $text)) { return; } } - foreach ($mem_prefs as $p) { + foreach ($job_prefs as $p) { + if ($p->xml_parse($parse_result, $name, $text)) { + return; + } + } + foreach ($disk_prefs as $p) { if ($p->xml_parse($parse_result, $name, $text)) { return; } } foreach ($net_prefs as $p) { - if (is_string($p)) continue; if ($p->xml_parse($parse_result, $name, $text)) { return; } @@ -374,32 +397,47 @@ function char_handler($parser, $x) { // state of prefs before parsing; defines prefs for new users // function default_prefs_global() { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; $p = new StdClass; - foreach ($cpu_prefs as $pref) { - if (is_string($pref)) continue; + foreach ($in_use_prefs as $pref) { $pref->set_default($p); } - foreach ($disk_prefs as $pref) { + foreach ($not_in_use_prefs as $pref) { $pref->set_default($p); } - foreach ($mem_prefs as $pref) { + foreach ($job_prefs as $pref) { + $pref->set_default($p); + } + foreach ($disk_prefs as $pref) { $pref->set_default($p); } foreach ($net_prefs as $pref) { - if (is_string($pref)) continue; $pref->set_default($p); } return $p; } -// parse prefs from XML to a struct +// if not-in-use prefs undefined, copy from in-use // +function set_niu_prefs($prefs) { + if (!$prefs->niu_max_ncpus_pct) { + $prefs->niu_max_ncpus_pct = $prefs->max_ncpus_pct; + } + if (!$prefs->niu_cpu_usage_limit) { + $prefs->niu_cpu_usage_limit = $prefs->cpu_usage_limit; + } + if (!$prefs->niu_suspend_cpu_usage) { + $prefs->niu_suspend_cpu_usage = $prefs->suspend_cpu_usage; + } +} +// parse prefs from XML to a struct +// function prefs_parse_global($prefs_xml) { global $parse_result; $parse_result = default_prefs_global(); @@ -408,72 +446,67 @@ function prefs_parse_global($prefs_xml) { xml_set_element_handler($xml_parser, "element_start_global", "element_end_global"); xml_set_character_data_handler($xml_parser, "char_handler"); xml_parse($xml_parser, $prefs_xml, 1); + set_niu_prefs($parse_result); return $parse_result; } // Display all venues as columns next to descriptions // function prefs_show_columns_global($prefs) { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; - row_top(CPU_LIMIT_DESC); - foreach ($cpu_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } + row_top(IN_USE_DESC); + foreach ($in_use_prefs as $p) { $p->show_cols($prefs); } - row_top(DISK_LIMIT_DESC); - foreach ($disk_prefs as $p) { + row_top(NOT_IN_USE_DESC); + foreach ($not_in_use_prefs as $p) { $p->show_cols($prefs); } - row_top(MEM_LIMIT_DESC); - foreach ($mem_prefs as $p) { + row_top(JOBS_DESC); + foreach ($job_prefs as $p) { + $p->show_cols($prefs); + } + row_top(DISK_DESC); + foreach ($disk_prefs as $p) { $p->show_cols($prefs); } - row_top(NETWORK_LIMIT_DESC); + row_top(NET_DESC); foreach ($net_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } $p->show_cols($prefs); } row_links("global", $prefs); } function prefs_show_global($prefs) { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; - row1(CPU_LIMIT_DESC); - foreach ($cpu_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } + row1(IN_USE_DESC); + foreach ($in_use_prefs as $p) { $p->show($prefs); } - row1(DISK_LIMIT_DESC); - foreach ($disk_prefs as $p) { + row1(NOT_IN_USE_DESC); + foreach ($not_in_use_prefs as $p) { $p->show($prefs); } - row1(MEM_LIMIT_DESC); - foreach ($mem_prefs as $p) { + row1(JOBS_DESC); + foreach ($job_prefs as $p) { + $p->show($prefs); + } + row1(DISK_DESC); + foreach ($disk_prefs as $p) { $p->show($prefs); } - row1(NETWORK_LIMIT_DESC); + row1(NET_DESC); foreach ($net_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } $p->show($prefs); } } @@ -491,7 +524,7 @@ function prefs_display_venue($prefs, $venue, $subset) { if ($x) { start_table(); - row_heading(tra("Separate preferences for %1", $venue)); + row_heading(tra("Separate preferences for %1", $venue), 'bg-info'); if ($subset == "global") { prefs_show_global($x); } else { @@ -604,33 +637,30 @@ function print_prefs_form( // Functions to display preference subsets as forms // function prefs_form_global($user, $prefs, $error=false) { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; - row1(CPU_LIMIT_DESC); - foreach ($cpu_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } + row1(IN_USE_DESC); + foreach ($in_use_prefs as $p) { $p->show_form_row($prefs, $error); } - row1(DISK_LIMIT_DESC); - foreach ($disk_prefs as $p) { + row1(NOT_IN_USE_DESC); + foreach ($not_in_use_prefs as $p) { $p->show_form_row($prefs, $error); } - row1(MEM_LIMIT_DESC); - foreach ($mem_prefs as $p) { + row1(JOBS_DESC); + foreach ($job_prefs as $p) { $p->show_form_row($prefs, $error); } - row1(NETWORK_LIMIT_DESC); + row1(DISK_DESC); + foreach ($disk_prefs as $p) { + $p->show_form_row($prefs, $error); + } + row1(NET_DESC); foreach ($net_prefs as $p) { - if (is_string($p)) { - group_header($p); - continue; - } $p->show_form_row($prefs, $error); } } @@ -697,24 +727,26 @@ function venue_parse_form(&$user) { // returns an object with errorvalues or false in success case // function prefs_global_parse_form(&$prefs) { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; $error = false; - foreach ($cpu_prefs as $p) { - if (is_string($p)) continue; + foreach ($in_use_prefs as $p) { $p->parse_form($prefs, $error); } - foreach ($disk_prefs as $p) { + foreach ($not_in_use_prefs as $p) { + $p->parse_form($prefs, $error); + } + foreach ($job_prefs as $p) { $p->parse_form($prefs, $error); } - foreach ($mem_prefs as $p) { + foreach ($disk_prefs as $p) { $p->parse_form($prefs, $error); } foreach ($net_prefs as $p) { - if (is_string($p)) continue; $p->parse_form($prefs, $error); } return $error; @@ -726,9 +758,10 @@ function prefs_global_parse_form(&$prefs) { // convert prefs from structure to XML // function global_prefs_make_xml($prefs, $primary=true) { - global $cpu_prefs; + global $in_use_prefs; + global $not_in_use_prefs; + global $job_prefs; global $disk_prefs; - global $mem_prefs; global $net_prefs; $xml = ""; @@ -738,18 +771,19 @@ function global_prefs_make_xml($prefs, $primary=true) { $xml = $xml."$now\n"; } - foreach ($cpu_prefs as $p) { - if (is_string($p)) continue; + foreach ($in_use_prefs as $p) { $xml .= $p->xml_string($prefs); } - foreach ($disk_prefs as $p) { + foreach ($not_in_use_prefs as $p) { $xml .= $p->xml_string($prefs); } - foreach ($mem_prefs as $p) { + foreach ($job_prefs as $p) { + $xml .= $p->xml_string($prefs); + } + foreach ($disk_prefs as $p) { $xml .= $p->xml_string($prefs); } foreach ($net_prefs as $p) { - if (is_string($p)) continue; $xml .= $p->xml_string($prefs); } diff --git a/html/user/add_venue.php b/html/user/add_venue.php index 65379e1e3df..3a70a6f8686 100644 --- a/html/user/add_venue.php +++ b/html/user/add_venue.php @@ -87,6 +87,7 @@ if ($subset == "global") { $prefs = default_prefs_global(); + set_niu_prefs($prefs); } else { $prefs = default_prefs_project(); } diff --git a/lib/prefs.cpp b/lib/prefs.cpp index e7d90be7264..6a781e18e19 100644 --- a/lib/prefs.cpp +++ b/lib/prefs.cpp @@ -60,6 +60,9 @@ void GLOBAL_PREFS_MASK::set_all() { net_end_hour = true; net_start_hour = true; network_wifi_only = true; + niu_max_ncpus_pct = true; + niu_cpu_usage_limit = true; + niu_suspend_cpu_usage = true; ram_max_used_busy_frac = true; ram_max_used_idle_frac = true; run_gpu_if_user_active = true; @@ -97,6 +100,9 @@ bool GLOBAL_PREFS_MASK::are_prefs_set() { if (net_start_hour) return true; if (network_wifi_only) return true; if (net_end_hour) return true; + if (niu_max_ncpus_pct) return true; + if (niu_cpu_usage_limit) return true; + if (niu_suspend_cpu_usage) return true; if (ram_max_used_busy_frac) return true; if (ram_max_used_idle_frac) return true; if (run_gpu_if_user_active) return true; @@ -232,6 +238,9 @@ void GLOBAL_PREFS::defaults() { #else network_wifi_only = false; #endif + niu_max_ncpus_pct = 100; + niu_cpu_usage_limit = 100; + niu_suspend_cpu_usage = 50; ram_max_used_busy_frac = 0.5; #ifdef ANDROID ram_max_used_idle_frac = 0.5; @@ -246,7 +255,7 @@ void GLOBAL_PREFS::defaults() { #else suspend_cpu_usage = 25; #endif - suspend_if_no_recent_input = 0; + suspend_if_no_recent_input = 60; vm_max_used_frac = 0.75; work_buf_additional_days = 0.5; work_buf_min_days = 0.1; @@ -388,6 +397,17 @@ int GLOBAL_PREFS::parse_override( if (net_times.start_hour == net_times.end_hour) { mask.net_start_hour = mask.net_end_hour = false; } + // if not-in-use prefs weren't specified, use in-use counterpart + // + if (!mask.niu_max_ncpus_pct) { + niu_max_ncpus_pct = max_ncpus_pct; + } + if (!mask.niu_cpu_usage_limit) { + niu_cpu_usage_limit = cpu_usage_limit; + } + if (!mask.niu_suspend_cpu_usage) { + niu_suspend_cpu_usage = suspend_cpu_usage; + } return 0; } if (in_venue) { @@ -460,6 +480,10 @@ int GLOBAL_PREFS::parse_override( mask.suspend_cpu_usage = true; continue; } + if (xp.parse_double("niu_suspend_cpu_usage", niu_suspend_cpu_usage)) { + mask.niu_suspend_cpu_usage = true; + continue; + } if (xp.parse_double("start_hour", cpu_times.start_hour)) { mask.start_hour = true; continue; @@ -512,6 +536,12 @@ int GLOBAL_PREFS::parse_override( mask.max_ncpus_pct = true; continue; } + if (xp.parse_double("niu_max_ncpus_pct", niu_max_ncpus_pct)) { + if (niu_max_ncpus_pct <= 0) niu_max_ncpus_pct = 100; + if (niu_max_ncpus_pct > 100) niu_max_ncpus_pct = 100; + mask.niu_max_ncpus_pct = true; + continue; + } if (xp.parse_int("max_cpus", max_ncpus)) { if (max_ncpus < 0) max_ncpus = 0; mask.max_ncpus = true; @@ -573,6 +603,13 @@ int GLOBAL_PREFS::parse_override( } continue; } + if (xp.parse_double("niu_cpu_usage_limit", dtemp)) { + if (dtemp <= 0) dtemp = 100; + if (dtemp > 100) dtemp = 100; + niu_cpu_usage_limit = dtemp; + mask.niu_cpu_usage_limit = true; + continue; + } if (xp.parse_double("daily_xfer_limit_mb", dtemp)) { if (dtemp >= 0) { daily_xfer_limit_mb = dtemp; @@ -652,6 +689,9 @@ int GLOBAL_PREFS::write(MIOFILE& f) { " %f\n" " %f\n" " %f\n" + " %f\n" + " %f\n" + " %f\n" " %f\n" " %f\n" " %f\n" @@ -688,6 +728,9 @@ int GLOBAL_PREFS::write(MIOFILE& f) { work_buf_min_days, work_buf_additional_days, max_ncpus_pct, + niu_max_ncpus_pct, + niu_cpu_usage_limit, + niu_suspend_cpu_usage, cpu_scheduling_period_minutes, disk_interval, disk_max_used_gb, @@ -778,7 +821,6 @@ int GLOBAL_PREFS::write_subset(MIOFILE& f, GLOBAL_PREFS_MASK& mask) { ); } if (mask.suspend_cpu_usage) { - f.printf(" %f\n", suspend_cpu_usage ); @@ -834,6 +876,17 @@ int GLOBAL_PREFS::write_subset(MIOFILE& f, GLOBAL_PREFS_MASK& mask) { if (mask.max_ncpus_pct) { f.printf(" %f\n", max_ncpus_pct); } + if (mask.niu_max_ncpus_pct) { + f.printf(" %f\n", niu_max_ncpus_pct); + } + if (mask.niu_cpu_usage_limit) { + f.printf(" %f\n", niu_cpu_usage_limit); + } + if (mask.niu_suspend_cpu_usage) { + f.printf(" %f\n", + niu_suspend_cpu_usage + ); + } if (mask.max_ncpus) { f.printf(" %d\n", max_ncpus); } diff --git a/lib/prefs.h b/lib/prefs.h index eb2166d71d4..da5ffe7ccd2 100644 --- a/lib/prefs.h +++ b/lib/prefs.h @@ -59,6 +59,9 @@ struct GLOBAL_PREFS_MASK { bool net_end_hour; bool net_start_hour; bool network_wifi_only; + bool niu_cpu_usage_limit; + bool niu_max_ncpus_pct; + bool niu_suspend_cpu_usage; bool ram_max_used_busy_frac; bool ram_max_used_idle_frac; bool run_if_user_active; @@ -143,8 +146,8 @@ struct TIME_PREFS : public TIME_SPAN { struct GLOBAL_PREFS { double mod_time; - double battery_charge_min_pct; - double battery_max_temperature; + double battery_charge_min_pct; // Android + double battery_max_temperature; // Android bool confirm_before_connecting; double cpu_scheduling_period_minutes; // length of a time slice. @@ -172,6 +175,9 @@ struct GLOBAL_PREFS { // not on public cell networks. // CAUTION: this only applies to file transfers. // scheduler RPCs are made regardless of this preference. + double niu_cpu_usage_limit; + double niu_max_ncpus_pct; + double niu_suspend_cpu_usage; double ram_max_used_busy_frac; double ram_max_used_idle_frac; bool run_gpu_if_user_active;