mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=12127
This commit is contained in:
parent
7b3e7cd518
commit
81effa6a7b
|
@ -55,7 +55,7 @@ extern "C"{
|
|||
#include "boinc_glut.h"
|
||||
|
||||
#include "filesys.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
|
||||
#include "gutil.h"
|
||||
|
||||
|
|
|
@ -1844,3 +1844,21 @@ Charlie 21 Feb 2007
|
|||
|
||||
clientgui/
|
||||
BOINCGUIApp.cpp
|
||||
|
||||
David 21 Feb 2007
|
||||
- split out string-related utility functions into a new file, str_util.C
|
||||
- more work on simulator
|
||||
- Add "Holy See" to country list
|
||||
|
||||
api/
|
||||
gutil_text.C
|
||||
client/
|
||||
*.C
|
||||
db/
|
||||
*.C
|
||||
lib/
|
||||
*.C
|
||||
sched/
|
||||
*.C
|
||||
tools/
|
||||
backend_lib.C
|
||||
|
|
|
@ -39,6 +39,8 @@ boinc_client_SOURCES = \
|
|||
cs_scheduler.C \
|
||||
cs_statefile.C \
|
||||
cs_trickle.C \
|
||||
dhrystone.C \
|
||||
dhrystone2.C \
|
||||
file_names.C \
|
||||
file_xfer.C \
|
||||
gui_http.C \
|
||||
|
@ -55,8 +57,7 @@ boinc_client_SOURCES = \
|
|||
ss_logic.C \
|
||||
time_stats.C \
|
||||
whetstone.C \
|
||||
dhrystone.C \
|
||||
dhrystone2.C
|
||||
work_fetch.C
|
||||
|
||||
boinc_client_DEPENDENCIES = $(LIBRSA)
|
||||
boinc_client_CPPFLAGS = -O3 -fomit-frame-pointer -fforce-addr -ffast-math $(AM_CPPFLAGS)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
#include "client_msgs.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "file_names.h"
|
||||
#include "filesys.h"
|
||||
#include "client_state.h"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "file_names.h"
|
||||
#include "parse.h"
|
||||
#include "filesys.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_msgs.h"
|
||||
|
||||
#include "acct_setup.h"
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#include "file_names.h"
|
||||
#include "parse.h"
|
||||
#include "shmem.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_msgs.h"
|
||||
#include "procinfo.h"
|
||||
#include "app.h"
|
||||
|
|
|
@ -55,6 +55,7 @@ using std::vector;
|
|||
#include "filesys.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "parse.h"
|
||||
#include "shmem.h"
|
||||
#include "client_msgs.h"
|
||||
|
|
|
@ -57,6 +57,7 @@ using std::vector;
|
|||
#include "filesys.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "shmem.h"
|
||||
#include "client_msgs.h"
|
||||
#include "client_state.h"
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#endif
|
||||
|
||||
#include "parse.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "filesys.h"
|
||||
|
@ -611,17 +612,6 @@ FILE_INFO* CLIENT_STATE::lookup_file_info(PROJECT* p, const char* name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Find the active task for a given result
|
||||
//
|
||||
ACTIVE_TASK* CLIENT_STATE::lookup_active_task_by_result(RESULT* rep) {
|
||||
for (unsigned int i = 0; i < active_tasks.active_tasks.size(); i ++) {
|
||||
if (active_tasks.active_tasks[i]->result == rep) {
|
||||
return active_tasks.active_tasks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// functions to create links between state objects
|
||||
// (which, in their XML form, reference one another by name)
|
||||
// Return nonzero if already in client state.
|
||||
|
|
|
@ -193,6 +193,10 @@ public:
|
|||
double new_version_check_time;
|
||||
string newer_version;
|
||||
|
||||
// --------------- app_graphics.C:
|
||||
public:
|
||||
ACTIVE_TASK* get_next_graphics_capable_app();
|
||||
|
||||
// --------------- auto_update.C:
|
||||
public:
|
||||
AUTO_UPDATE auto_update;
|
||||
|
@ -214,7 +218,6 @@ public:
|
|||
RESULT* lookup_result(PROJECT*, const char*);
|
||||
WORKUNIT* lookup_workunit(PROJECT*, const char*);
|
||||
APP_VERSION* lookup_app_version(APP*, int);
|
||||
ACTIVE_TASK* lookup_active_task_by_result(RESULT*);
|
||||
int detach_project(PROJECT*);
|
||||
int report_result_error(RESULT&, const char *format, ...);
|
||||
int reset_project(PROJECT*);
|
||||
|
@ -305,7 +308,7 @@ public:
|
|||
double estimate_cpu_time(WORKUNIT&);
|
||||
double get_fraction_done(RESULT* result);
|
||||
int input_files_available(RESULT*, bool);
|
||||
ACTIVE_TASK* get_next_graphics_capable_app();
|
||||
ACTIVE_TASK* lookup_active_task_by_result(RESULT*);
|
||||
int ncpus;
|
||||
// number of usable cpus
|
||||
private:
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "log_flags.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_state.h"
|
||||
#include "pers_file_xfer.h"
|
||||
|
||||
|
@ -137,7 +138,6 @@ int PROJECT::parse_state(MIOFILE& in) {
|
|||
else if (parse_double(buf, "<user_total_credit>", user_total_credit)) continue;
|
||||
else if (parse_double(buf, "<user_expavg_credit>", user_expavg_credit)) continue;
|
||||
else if (parse_double(buf, "<user_create_time>", user_create_time)) {
|
||||
validate_time(user_create_time);
|
||||
continue;
|
||||
}
|
||||
else if (parse_int(buf, "<rpc_seqno>", rpc_seqno)) continue;
|
||||
|
@ -145,7 +145,6 @@ int PROJECT::parse_state(MIOFILE& in) {
|
|||
else if (parse_double(buf, "<host_total_credit>", host_total_credit)) continue;
|
||||
else if (parse_double(buf, "<host_expavg_credit>", host_expavg_credit)) continue;
|
||||
else if (parse_double(buf, "<host_create_time>", host_create_time)) {
|
||||
validate_time(user_create_time);
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<code_sign_key>")) {
|
||||
|
@ -160,7 +159,6 @@ int PROJECT::parse_state(MIOFILE& in) {
|
|||
else if (parse_int(buf, "<nrpc_failures>", nrpc_failures)) continue;
|
||||
else if (parse_int(buf, "<master_fetch_failures>", master_fetch_failures)) continue;
|
||||
else if (parse_double(buf, "<min_rpc_time>", min_rpc_time)) {
|
||||
validate_time(min_rpc_time);
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<master_url_fetch_pending/>")) master_url_fetch_pending = true;
|
||||
|
@ -1484,7 +1482,6 @@ int RESULT::parse_server(MIOFILE& in) {
|
|||
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
|
||||
if (parse_str(buf, "<wu_name>", wu_name, sizeof(wu_name))) continue;
|
||||
if (parse_double(buf, "<report_deadline>", report_deadline)) {
|
||||
validate_time(report_deadline);
|
||||
continue;
|
||||
}
|
||||
if (match_tag(buf, "<file_ref>")) {
|
||||
|
@ -1522,7 +1519,6 @@ int RESULT::parse_state(MIOFILE& in) {
|
|||
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
|
||||
if (parse_str(buf, "<wu_name>", wu_name, sizeof(wu_name))) continue;
|
||||
if (parse_double(buf, "<report_deadline>", report_deadline)) {
|
||||
validate_time(report_deadline);
|
||||
continue;
|
||||
}
|
||||
if (match_tag(buf, "<file_ref>")) {
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include "client_state.h"
|
||||
#endif
|
||||
#include "client_msgs.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "log_flags.h"
|
||||
|
||||
using std::vector;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "filesys.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_state.h"
|
||||
#include "client_msgs.h"
|
||||
#include "log_flags.h"
|
||||
|
|
|
@ -374,4 +374,16 @@ void CLIENT_STATE::request_work_fetch(const char* where) {
|
|||
must_check_work_fetch = true;
|
||||
}
|
||||
|
||||
// Find the active task for a given result
|
||||
//
|
||||
ACTIVE_TASK* CLIENT_STATE::lookup_active_task_by_result(RESULT* rep) {
|
||||
for (unsigned int i = 0; i < active_tasks.active_tasks.size(); i ++) {
|
||||
if (active_tasks.active_tasks[i]->result == rep) {
|
||||
return active_tasks.active_tasks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *BOINC_RCSID_7bf63ad771 = "$Id$";
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#endif
|
||||
|
||||
#include "main.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "client_msgs.h"
|
||||
#include "client_state.h"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include "md5_file.h"
|
||||
#include "crypt.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
#include "error_numbers.h"
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
#include "parse.h"
|
||||
#include "file_names.h"
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "file_names.h"
|
||||
#include "filesys.h"
|
||||
#include "parse.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "client_msgs.h"
|
||||
|
@ -62,173 +63,6 @@ using std::string;
|
|||
//
|
||||
#define REPORT_DEADLINE_CUSHION ((double)SECONDS_PER_DAY)
|
||||
|
||||
static const char* urgency_name(int urgency) {
|
||||
switch(urgency) {
|
||||
case WORK_FETCH_DONT_NEED: return "Don't need";
|
||||
case WORK_FETCH_OK: return "OK";
|
||||
case WORK_FETCH_NEED: return "Need";
|
||||
case WORK_FETCH_NEED_IMMEDIATELY: return "Need immediately";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
// how many CPUs should this project occupy on average,
|
||||
// based on its resource share relative to a given set
|
||||
//
|
||||
int CLIENT_STATE::proj_min_results(PROJECT* p, double subset_resource_share) {
|
||||
if (p->non_cpu_intensive) {
|
||||
return 1;
|
||||
}
|
||||
if (!subset_resource_share) return 1; // TODO - fix
|
||||
return (int)(ceil(ncpus*p->resource_share/subset_resource_share));
|
||||
}
|
||||
|
||||
void CLIENT_STATE::check_project_timeout() {
|
||||
unsigned int i;
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
PROJECT* p = projects[i];
|
||||
if (p->possibly_backed_off && now > p->min_rpc_time) {
|
||||
p->possibly_backed_off = false;
|
||||
request_work_fetch("Project backoff ended");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PROJECT::set_min_rpc_time(double future_time, const char* reason) {
|
||||
if (future_time > min_rpc_time) {
|
||||
min_rpc_time = future_time;
|
||||
possibly_backed_off = true;
|
||||
msg_printf(this, MSG_INFO,
|
||||
"Deferring communication for %s",
|
||||
timediff_format(min_rpc_time - gstate.now).c_str()
|
||||
);
|
||||
msg_printf(this, MSG_INFO, "Reason: %s\n", reason);
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if we should not contact the project yet.
|
||||
//
|
||||
bool PROJECT::waiting_until_min_rpc_time() {
|
||||
return (min_rpc_time > gstate.now);
|
||||
}
|
||||
|
||||
// find a project that needs to have its master file fetched
|
||||
//
|
||||
PROJECT* CLIENT_STATE::next_project_master_pending() {
|
||||
unsigned int i;
|
||||
PROJECT* p;
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
p = projects[i];
|
||||
if (p->waiting_until_min_rpc_time()) continue;
|
||||
if (p->suspended_via_gui) continue;
|
||||
if (p->master_url_fetch_pending) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// find a project for which a scheduler RPC is pending
|
||||
// and we're not backed off
|
||||
//
|
||||
PROJECT* CLIENT_STATE::next_project_sched_rpc_pending() {
|
||||
unsigned int i;
|
||||
PROJECT* p;
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
p = projects[i];
|
||||
if (p->waiting_until_min_rpc_time()) continue;
|
||||
if (p->next_rpc_time && p->next_rpc_time<now) {
|
||||
p->sched_rpc_pending = RPC_REASON_PROJECT_REQ;
|
||||
p->next_rpc_time = 0;
|
||||
}
|
||||
//if (p->suspended_via_gui) continue;
|
||||
// do the RPC even if suspended.
|
||||
// This is critical for acct mgrs, to propagate new host CPIDs
|
||||
//
|
||||
if (p->sched_rpc_pending) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PROJECT* CLIENT_STATE::next_project_trickle_up_pending() {
|
||||
unsigned int i;
|
||||
PROJECT* p;
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
p = projects[i];
|
||||
if (p->waiting_until_min_rpc_time()) continue;
|
||||
if (p->suspended_via_gui) continue;
|
||||
if (p->trickle_up_pending) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the best project to fetch work from, NULL if none
|
||||
//
|
||||
// Pick the one with largest (long term debt - amount of current work)
|
||||
//
|
||||
// PRECONDITIONS:
|
||||
// - work_request_urgency and work_request set for all projects
|
||||
// - CLIENT_STATE::overall_work_fetch_urgency is set
|
||||
// (by previous call to compute_work_requests())
|
||||
//
|
||||
PROJECT* CLIENT_STATE::next_project_need_work() {
|
||||
PROJECT *p, *p_prospect = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
p = projects[i];
|
||||
if (p->work_request_urgency == WORK_FETCH_DONT_NEED) continue;
|
||||
if (p->work_request == 0) continue;
|
||||
if (!p->contactable()) continue;
|
||||
|
||||
// if we don't need work, only get work from non-cpu intensive projects.
|
||||
//
|
||||
if (overall_work_fetch_urgency == WORK_FETCH_DONT_NEED && !p->non_cpu_intensive) continue;
|
||||
|
||||
// if we don't really need work,
|
||||
// and we don't really need work from this project, pass.
|
||||
//
|
||||
if (overall_work_fetch_urgency == WORK_FETCH_OK) {
|
||||
if (p->work_request_urgency <= WORK_FETCH_OK) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_prospect) {
|
||||
if (p->work_request_urgency == WORK_FETCH_OK &&
|
||||
p_prospect->work_request_urgency > WORK_FETCH_OK
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->long_term_debt + p->cpu_shortfall < p_prospect->long_term_debt + p_prospect->cpu_shortfall
|
||||
&& !p->non_cpu_intensive
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
p_prospect = p;
|
||||
}
|
||||
if (p_prospect && (p_prospect->work_request <= 0)) {
|
||||
p_prospect->work_request = 1.0;
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(0, MSG_INFO,
|
||||
"[work_fetch_debug] next_project_need_work: project picked %s",
|
||||
p_prospect->project_name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return p_prospect;
|
||||
}
|
||||
|
||||
// Write a scheduler request to a disk file,
|
||||
// to be sent to a scheduling server
|
||||
|
@ -454,343 +288,6 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// find a project with finished results that should be reported.
|
||||
// This means:
|
||||
// - we're not backing off contacting the project
|
||||
// - the result is ready_to_report (compute done; files uploaded)
|
||||
// - we're either within a day of the report deadline,
|
||||
// or at least work_buf_min_days time has elapsed since
|
||||
// result was completed,
|
||||
// or we have a sporadic connection
|
||||
//
|
||||
PROJECT* CLIENT_STATE::find_project_with_overdue_results() {
|
||||
unsigned int i;
|
||||
RESULT* r;
|
||||
|
||||
for (i=0; i<results.size(); i++) {
|
||||
r = results[i];
|
||||
// return the project for this result to report if:
|
||||
//
|
||||
|
||||
PROJECT* p = r->project;
|
||||
if (p->waiting_until_min_rpc_time()) continue;
|
||||
if (p->suspended_via_gui) continue;
|
||||
|
||||
if (!r->ready_to_report) continue;
|
||||
if (net_status.have_sporadic_connection) {
|
||||
return p;
|
||||
}
|
||||
double cushion = std::max(REPORT_DEADLINE_CUSHION, work_buf_min());
|
||||
if (gstate.now > r->report_deadline - cushion) {
|
||||
return p;
|
||||
}
|
||||
if (gstate.now > r->completed_time + work_buf_min()) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Handle the case where the report is due
|
||||
// before the next reconnect is likely.
|
||||
//
|
||||
if (gstate.now > r->report_deadline - work_buf_min()) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the fraction of time a given CPU is working for BOINC
|
||||
//
|
||||
double CLIENT_STATE::overall_cpu_frac() {
|
||||
double running_frac = time_stats.on_frac * time_stats.active_frac * time_stats.cpu_efficiency;
|
||||
if (running_frac < 0.01) running_frac = 0.01;
|
||||
if (running_frac > 1) running_frac = 1;
|
||||
return running_frac;
|
||||
}
|
||||
|
||||
// the expected number of CPU seconds completed by the client
|
||||
// in a second of wall-clock time.
|
||||
// May be > 1 on a multiprocessor.
|
||||
//
|
||||
double CLIENT_STATE::avg_proc_rate() {
|
||||
return ncpus*overall_cpu_frac();
|
||||
}
|
||||
|
||||
// estimate wall-clock time until the number of uncompleted results
|
||||
// for project p will reach k,
|
||||
// given the total resource share of a set of competing projects
|
||||
//
|
||||
double CLIENT_STATE::time_until_work_done(
|
||||
PROJECT *p, int k, double subset_resource_share
|
||||
) {
|
||||
int num_results_to_skip = k;
|
||||
double est = 0;
|
||||
|
||||
// total up the estimated time for this project's unstarted
|
||||
// and partially completed results,
|
||||
// omitting the last k
|
||||
//
|
||||
for (vector<RESULT*>::reverse_iterator iter = results.rbegin();
|
||||
iter != results.rend(); iter++
|
||||
) {
|
||||
RESULT *rp = *iter;
|
||||
if (rp->project != p
|
||||
|| rp->state() > RESULT_FILES_DOWNLOADED
|
||||
|| rp->ready_to_report
|
||||
) continue;
|
||||
if (num_results_to_skip > 0) {
|
||||
--num_results_to_skip;
|
||||
continue;
|
||||
}
|
||||
if (rp->project->non_cpu_intensive) {
|
||||
// if it is a non_cpu intensive project,
|
||||
// it needs only one at a time.
|
||||
//
|
||||
est = max(rp->estimated_cpu_time_remaining(), work_buf_min());
|
||||
} else {
|
||||
est += rp->estimated_cpu_time_remaining();
|
||||
}
|
||||
}
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[work_fetch_debug] time_until_work_done(): est %f ssr %f apr %f prs %f",
|
||||
est, subset_resource_share, avg_proc_rate(), p->resource_share
|
||||
);
|
||||
}
|
||||
if (subset_resource_share) {
|
||||
double apr = avg_proc_rate()*p->resource_share/subset_resource_share;
|
||||
return est/apr;
|
||||
} else {
|
||||
return est/avg_proc_rate(); // TODO - fix
|
||||
}
|
||||
}
|
||||
|
||||
// Top-level function for work fetch policy.
|
||||
// Outputs:
|
||||
// - overall_work_fetch_urgency
|
||||
// - for each contactable project:
|
||||
// - work_request and work_request_urgency
|
||||
//
|
||||
// Notes:
|
||||
// - at most 1 CPU-intensive project will have a nonzero work_request
|
||||
// and a work_request_urgency higher than DONT_NEED.
|
||||
// This prevents projects with low LTD from getting work
|
||||
// even though there was a higher LTD project that should get work.
|
||||
// - all non-CPU-intensive projects that need work
|
||||
// and are contactable will have a work request of 1.
|
||||
//
|
||||
// return false
|
||||
//
|
||||
bool CLIENT_STATE::compute_work_requests() {
|
||||
unsigned int i;
|
||||
static double last_time = 0;
|
||||
|
||||
if (gstate.now - last_time >= 60) {
|
||||
gstate.request_work_fetch("timer");
|
||||
}
|
||||
if (!must_check_work_fetch) return 0;
|
||||
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(0, MSG_INFO, "[work_fetch_debug] compute_work_requests(): start");
|
||||
}
|
||||
last_time = gstate.now;
|
||||
must_check_work_fetch = false;
|
||||
|
||||
compute_nuploading_results();
|
||||
adjust_debts();
|
||||
|
||||
rr_simulation();
|
||||
|
||||
// compute per-project and overall urgency
|
||||
//
|
||||
bool possible_deadline_miss = false;
|
||||
bool project_shortfall = false;
|
||||
bool non_cpu_intensive_needs_work = false;
|
||||
for (i=0; i< projects.size(); i++) {
|
||||
PROJECT* p = projects[i];
|
||||
if (p->non_cpu_intensive) {
|
||||
if (p->runnable() || !p->contactable()) {
|
||||
p->work_request = 0;
|
||||
p->work_request_urgency = WORK_FETCH_DONT_NEED;
|
||||
} else {
|
||||
p->work_request = 1.0;
|
||||
p->work_request_urgency = WORK_FETCH_NEED_IMMEDIATELY;
|
||||
non_cpu_intensive_needs_work = true;
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] non-CPU-intensive project needs work"
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
p->work_request_urgency = WORK_FETCH_DONT_NEED;
|
||||
p->work_request = 0;
|
||||
if (p->rr_sim_deadlines_missed) {
|
||||
possible_deadline_miss = true;
|
||||
}
|
||||
if (p->cpu_shortfall && p->long_term_debt > -global_prefs.cpu_scheduling_period_minutes * 60) {
|
||||
project_shortfall = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu_shortfall <= 0.0 && (possible_deadline_miss || !project_shortfall)) {
|
||||
overall_work_fetch_urgency = WORK_FETCH_DONT_NEED;
|
||||
} else if (no_work_for_a_cpu()) {
|
||||
overall_work_fetch_urgency = WORK_FETCH_NEED_IMMEDIATELY;
|
||||
} else if (cpu_shortfall > 0) {
|
||||
overall_work_fetch_urgency = WORK_FETCH_NEED;
|
||||
} else {
|
||||
overall_work_fetch_urgency = WORK_FETCH_OK;
|
||||
}
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(0, MSG_INFO,
|
||||
"[work_fetch_debug] compute_work_requests(): cpu_shortfall %f, overall urgency %s",
|
||||
cpu_shortfall, urgency_name(overall_work_fetch_urgency)
|
||||
);
|
||||
}
|
||||
if (overall_work_fetch_urgency == WORK_FETCH_DONT_NEED) {
|
||||
if (non_cpu_intensive_needs_work) {
|
||||
overall_work_fetch_urgency = WORK_FETCH_NEED_IMMEDIATELY;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// loop over projects, and pick one to get work from
|
||||
//
|
||||
double prrs = potentially_runnable_resource_share();
|
||||
PROJECT *pbest = NULL;
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
PROJECT *p = projects[i];
|
||||
|
||||
// see if this project can be ruled out completely
|
||||
//
|
||||
if (p->non_cpu_intensive) continue;
|
||||
if (!p->contactable()) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO, "[work_fetch_debug] work fetch: project not contactable");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (p->deadlines_missed
|
||||
&& overall_work_fetch_urgency != WORK_FETCH_NEED_IMMEDIATELY
|
||||
) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] project has %d deadline misses",
|
||||
p->deadlines_missed
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (p->some_download_stalled()) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] project has stalled download"
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->some_result_suspended()) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO, "[work_fetch_debug] project has suspended result");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->overworked() && overall_work_fetch_urgency < WORK_FETCH_NEED) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO, "[work_fetch_debug] project is overworked");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (p->cpu_shortfall == 0.0 && overall_work_fetch_urgency < WORK_FETCH_NEED) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO, "[work_fetch_debug] project has no shortfall");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (p->nuploading_results > 2*ncpus) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO, "[work_fetch_debug] project has %d uploading results", p->nuploading_results);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if this project is better than our current best
|
||||
//
|
||||
if (pbest) {
|
||||
// avoid getting work from a project in deadline trouble
|
||||
//
|
||||
if (p->deadlines_missed && !pbest->deadlines_missed) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] project has deadline misses, %s doesn't",
|
||||
pbest->get_project_name()
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// avoid getting work from an overworked project
|
||||
//
|
||||
if (p->overworked() && !pbest->overworked()) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] project is overworked, %s isn't",
|
||||
pbest->get_project_name()
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// get work from project with highest LTD
|
||||
//
|
||||
if (pbest->long_term_debt + pbest->cpu_shortfall > p->long_term_debt + p->cpu_shortfall) {
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"[work_fetch_debug] project has less LTD than %s",
|
||||
pbest->get_project_name()
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pbest = p;
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(pbest, MSG_INFO, "[work_fetch_debug] best project so far");
|
||||
}
|
||||
}
|
||||
|
||||
if (pbest) {
|
||||
pbest->work_request = config.work_request_factor * max(
|
||||
pbest->cpu_shortfall,
|
||||
cpu_shortfall * (prrs ? pbest->resource_share/prrs : 1)
|
||||
);
|
||||
|
||||
if (!pbest->nearly_runnable()) {
|
||||
pbest->work_request_urgency = WORK_FETCH_NEED_IMMEDIATELY;
|
||||
} else if (pbest->cpu_shortfall) {
|
||||
pbest->work_request_urgency = WORK_FETCH_NEED;
|
||||
} else {
|
||||
pbest->work_request_urgency = WORK_FETCH_OK;
|
||||
}
|
||||
|
||||
if (log_flags.work_fetch_debug) {
|
||||
msg_printf(pbest, MSG_INFO,
|
||||
"[work_fetch_debug] compute_work_requests(): work req %f, shortfall %f, urgency %s\n",
|
||||
pbest->work_request, pbest->cpu_shortfall,
|
||||
urgency_name(pbest->work_request_urgency)
|
||||
);
|
||||
}
|
||||
} else if (non_cpu_intensive_needs_work) {
|
||||
overall_work_fetch_urgency = WORK_FETCH_NEED_IMMEDIATELY;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// called from the client's polling loop.
|
||||
// initiate scheduler RPC activity if needed and possible
|
||||
//
|
||||
|
@ -1301,62 +798,4 @@ int CLIENT_STATE::handle_scheduler_reply(
|
|||
return 0;
|
||||
}
|
||||
|
||||
double CLIENT_STATE::work_needed_secs() {
|
||||
double total_work = 0;
|
||||
for(unsigned int i=0; i<results.size(); i++) {
|
||||
if (results[i]->project->non_cpu_intensive) continue;
|
||||
total_work += results[i]->estimated_cpu_time_remaining();
|
||||
}
|
||||
double x = work_buf_min() * avg_proc_rate() - total_work;
|
||||
if (x < 0) {
|
||||
return 0;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// called when benchmarks change
|
||||
//
|
||||
void CLIENT_STATE::scale_duration_correction_factors(double factor) {
|
||||
if (factor <= 0) return;
|
||||
for (unsigned int i=0; i<projects.size(); i++) {
|
||||
PROJECT* p = projects[i];
|
||||
p->duration_correction_factor *= factor;
|
||||
}
|
||||
if (log_flags.cpu_sched_debug) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[cpu_sched_debug] scaling duration correction factors by %f",
|
||||
factor
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Choose a new host CPID.
|
||||
// If using account manager, do scheduler RPCs
|
||||
// to all acct-mgr-attached projects to propagate the CPID
|
||||
//
|
||||
void CLIENT_STATE::generate_new_host_cpid() {
|
||||
host_info.generate_host_cpid();
|
||||
for (unsigned int i=0; i<projects.size(); i++) {
|
||||
if (projects[i]->attached_via_acct_mgr) {
|
||||
projects[i]->sched_rpc_pending = RPC_REASON_ACCT_MGR_REQ;
|
||||
projects[i]->set_min_rpc_time(now + 15, "Sending new host CPID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLIENT_STATE::compute_nuploading_results() {
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
projects[i]->nuploading_results = 0;
|
||||
}
|
||||
for (i=0; i<results.size(); i++) {
|
||||
RESULT* rp = results[i];
|
||||
if (rp->state() == RESULT_FILES_UPLOADING) {
|
||||
rp->project->nuploading_results++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *BOINC_RCSID_d35a4a7711 = "$Id$";
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#endif
|
||||
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "filesys.h"
|
||||
#include "file_names.h"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "file_names.h"
|
||||
#include "filesys.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_state.h"
|
||||
|
||||
using std::string;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "filesys.h"
|
||||
#include "error_numbers.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "client_msgs.h"
|
||||
#include "client_state.h"
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "network.h"
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "parse.h"
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "parse.h"
|
||||
#include "file_names.h"
|
||||
#include "client_msgs.h"
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
#include "client_types.h"
|
||||
#include "filesys.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "client_state.h"
|
||||
#include "hostinfo_network.h"
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "filesys.h"
|
||||
#include "client_msgs.h"
|
||||
#include "log_flags.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "network.h"
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef void (CALLBACK* ClientLibraryShutdown)();
|
|||
|
||||
#include "diagnostics.h"
|
||||
#include "error_numbers.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "prefs.h"
|
||||
#include "filesys.h"
|
||||
|
|
|
@ -4,11 +4,20 @@ CXXFLAGS = -g -DSIM \
|
|||
|
||||
OBJS = sim.o \
|
||||
client_msgs.o \
|
||||
client_types.o \
|
||||
cs_apps.o \
|
||||
cs_prefs.o \
|
||||
cpu_sched.o \
|
||||
log_flags.o \
|
||||
../lib/parse.o \
|
||||
time_stats.o \
|
||||
work_fetch.o \
|
||||
../lib/hostinfo.o \
|
||||
../lib/filesys.o \
|
||||
../lib/mfile.o \
|
||||
../lib/miofile.o
|
||||
../lib/miofile.o \
|
||||
../lib/parse.o \
|
||||
../lib/prefs.o \
|
||||
../lib/str_util.o
|
||||
|
||||
all: sim
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "parse.h"
|
||||
#include "time.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "error_numbers.h"
|
||||
|
||||
#include "client_msgs.h"
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "error_numbers.h"
|
||||
#include "md5_file.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
|
||||
#include "log_flags.h"
|
||||
|
@ -413,11 +413,9 @@ int PERS_FILE_XFER::parse(MIOFILE& fin) {
|
|||
if (match_tag(buf, "</persistent_file_xfer>")) return 0;
|
||||
else if (parse_int(buf, "<num_retries>", nretry)) continue;
|
||||
else if (parse_double(buf, "<first_request_time>", first_request_time)) {
|
||||
validate_time(first_request_time);
|
||||
continue;
|
||||
}
|
||||
else if (parse_double(buf, "<next_request_time>", next_request_time)) {
|
||||
validate_time(next_request_time);
|
||||
continue;
|
||||
}
|
||||
else if (parse_double(buf, "<time_so_far>", time_so_far)) continue;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <ctime>
|
||||
#endif
|
||||
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
|
|
29
client/sim.C
29
client/sim.C
|
@ -1,6 +1,35 @@
|
|||
#include "str_util.h"
|
||||
#include "sim.h"
|
||||
|
||||
CLIENT_STATE gstate;
|
||||
bool g_use_sandbox;
|
||||
|
||||
void CLIENT_STATE::set_client_state_dirty(char const*) {
|
||||
}
|
||||
|
||||
void show_message(PROJECT *p, char* msg, int priority) {
|
||||
const char* x;
|
||||
char message[1024];
|
||||
char* time_string = time_to_string(gstate.now);
|
||||
|
||||
if (priority == MSG_INTERNAL_ERROR) {
|
||||
strcpy(message, "[error] ");
|
||||
strlcpy(message+8, msg, sizeof(message)-8);
|
||||
} else {
|
||||
strlcpy(message, msg, sizeof(message));
|
||||
}
|
||||
while (strlen(message)&&message[strlen(message)-1] == '\n') {
|
||||
message[strlen(message)-1] = 0;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
x = p->get_project_name();
|
||||
} else {
|
||||
x = "---";
|
||||
}
|
||||
|
||||
printf("%s [%s] %s\n", time_string, x, message);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "boinc_db.h"
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <mysql.h>
|
||||
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "db_base.h"
|
||||
|
||||
#ifdef _USING_FCGI_
|
||||
|
|
|
@ -19,6 +19,15 @@ function last_mod($datefile) {
|
|||
return gmdate("g:i A \U\T\C, F d Y", filemtime($datefile));
|
||||
}
|
||||
|
||||
function html_tag() {
|
||||
global $language_in_use;
|
||||
if ($language_in_use == 'ar') {
|
||||
echo "<html dir=\"rtl\">";
|
||||
} else {
|
||||
echo "<html>";
|
||||
}
|
||||
}
|
||||
|
||||
function page_head($title) {
|
||||
global $book;
|
||||
global $chap_num;
|
||||
|
@ -30,8 +39,8 @@ function page_head($title) {
|
|||
header("Content-type: text/html; charset=".tr(CHARSET));
|
||||
}
|
||||
|
||||
html_tag();
|
||||
echo "
|
||||
<html>
|
||||
<head>
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"white.css\"/>
|
||||
<link rel=\"shortcut icon\" href=\"iconsmall.ico\"/>
|
||||
|
|
|
@ -139,8 +139,8 @@ function show_nsf() {
|
|||
";
|
||||
}
|
||||
|
||||
html_tag();
|
||||
echo "
|
||||
<html>
|
||||
<head>
|
||||
<link rel=\"shortcut icon\" href=\"iconsmall.ico\">
|
||||
<link rel=\"stylesheet\" type=text/css href=white.css>
|
||||
|
|
|
@ -96,6 +96,7 @@ $countries = array(
|
|||
"Guinea-Bissau",
|
||||
"Guyana",
|
||||
"Haiti",
|
||||
"Holy See (Vatican City)",
|
||||
"Honduras",
|
||||
"Hong Kong",
|
||||
"Hungary",
|
||||
|
|
|
@ -542,7 +542,7 @@ FROM result WHERE
|
|||
$main_query .= "workunitid=$query_wuid and ";
|
||||
}
|
||||
if ($query_mod_time) {
|
||||
$main_query .= "mod_time > DATE_SUB( NOW()+0, INTERVAL $query_mod_time SECOND )+0 and ";
|
||||
$main_query .= "mod_time > DATE_SUB( NOW(), INTERVAL $query_mod_time SECOND )+0 and ";
|
||||
}
|
||||
|
||||
$main_query .= "1=1";
|
||||
|
|
|
@ -66,6 +66,7 @@ libboinc_a_SOURCES = \
|
|||
procinfo_unix.C \
|
||||
proxy_info.C \
|
||||
shmem.C \
|
||||
str_util.C \
|
||||
util.C \
|
||||
$(mac_sources)
|
||||
|
||||
|
@ -86,6 +87,7 @@ include_HEADERS = \
|
|||
prefs.h \
|
||||
proxy_info.h \
|
||||
std_fixes.h \
|
||||
str_util.h \
|
||||
util.h
|
||||
|
||||
## install header-files with prefix-subdir BOINC/ to avoid name-conflicts
|
||||
|
|
|
@ -24,11 +24,12 @@
|
|||
#ifndef _WIN32
|
||||
#include "config.h"
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
#include "miofile.h"
|
||||
#include "app_ipc.h"
|
||||
|
|
|
@ -41,6 +41,7 @@ using std::string;
|
|||
#include "gui_rpc_client.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "version.h"
|
||||
#include "common_defs.h"
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef BOOL (CALLBACK* FreeFn)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULAR
|
|||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "filesys.h"
|
||||
#ifdef SANDBOX
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "diagnostics.h"
|
||||
#include "parse.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "miofile.h"
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
#include "diagnostics.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "miofile.h"
|
||||
#include "md5_file.h"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <string>
|
||||
#endif
|
||||
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "msg_log.h"
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#endif
|
||||
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "parse.h"
|
||||
|
||||
#ifdef _USING_FCGI_
|
||||
|
|
681
lib/util.C
681
lib/util.C
|
@ -70,142 +70,6 @@ using std::vector;
|
|||
|
||||
int g_use_sandbox = 0;
|
||||
|
||||
// Use this instead of strncpy().
|
||||
// Result will always be null-terminated, and it's faster.
|
||||
// see http://www.gratisoft.us/todd/papers/strlcpy.html
|
||||
//
|
||||
#if !defined(HAVE_STRLCPY)
|
||||
size_t strlcpy(char *dst, const char *src, size_t size) {
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size-1 : ret;
|
||||
memcpy(dst, src, len);
|
||||
dst[len] = '\0';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRLCAT)
|
||||
size_t strlcat(char *dst, const char *src, size_t size) {
|
||||
size_t dst_len = strlen(dst);
|
||||
size_t src_len = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (src_len >= size-dst_len) ? (size-dst_len-1) : src_len;
|
||||
memcpy(&dst[dst_len], src, len);
|
||||
dst[dst_len + len] = '\0';
|
||||
}
|
||||
|
||||
return dst_len + src_len;
|
||||
}
|
||||
#endif // !HAVE_STRLCAT
|
||||
|
||||
// Converts a double precision time (where the value of 1 represents
|
||||
// a day) into a string. smallest_timescale determines the smallest
|
||||
// unit of time division used
|
||||
// smallest_timescale: 0=seconds, 1=minutes, 2=hours, 3=days, 4=years
|
||||
//
|
||||
int ndays_to_string (double x, int smallest_timescale, char *buf) {
|
||||
double years, days, hours, minutes, seconds;
|
||||
char year_buf[64], day_buf[16], hour_buf[16], min_buf[16], sec_buf[16];
|
||||
|
||||
if (x < 0 || buf == NULL) return ERR_NULL;
|
||||
|
||||
years = x / 365.25;
|
||||
days = fmod(x, 365.25);
|
||||
hours = fmod(x*24, 24);
|
||||
minutes = fmod(x*24*60, 60);
|
||||
seconds = fmod(x*24*60*60, 60);
|
||||
|
||||
if (smallest_timescale==4) {
|
||||
sprintf( year_buf, "%.3f yr ", years );
|
||||
} else if (years > 1 && smallest_timescale < 4) {
|
||||
sprintf( year_buf, "%d yr ", (int)years );
|
||||
} else {
|
||||
strcpy( year_buf, "" );
|
||||
}
|
||||
|
||||
if (smallest_timescale==3) {
|
||||
sprintf( day_buf, "%.2f day%s ", days, (days>1?"s":"") );
|
||||
} else if (days > 1 && smallest_timescale < 3) {
|
||||
sprintf( day_buf, "%d day%s ", (int)days, (days>1?"s":"") );
|
||||
} else {
|
||||
strcpy( day_buf, "" );
|
||||
}
|
||||
|
||||
if (smallest_timescale==2) {
|
||||
sprintf( hour_buf, "%.2f hr ", hours );
|
||||
} else if (hours > 1 && smallest_timescale < 2) {
|
||||
sprintf( hour_buf, "%d hr ", (int)hours );
|
||||
} else {
|
||||
strcpy( hour_buf, "" );
|
||||
}
|
||||
|
||||
if (smallest_timescale==1) {
|
||||
sprintf( min_buf, "%.2f min ", minutes );
|
||||
} else if (minutes > 1 && smallest_timescale < 1) {
|
||||
sprintf( min_buf, "%d min ", (int)minutes );
|
||||
} else {
|
||||
strcpy( min_buf, "" );
|
||||
}
|
||||
|
||||
if (smallest_timescale==0) {
|
||||
sprintf( sec_buf, "%.2f sec ", seconds );
|
||||
} else if (seconds > 1 && smallest_timescale < 0) {
|
||||
sprintf( sec_buf, "%d sec ", (int)seconds );
|
||||
} else {
|
||||
strcpy( sec_buf, "" );
|
||||
}
|
||||
// the "-0.05" below is to prevent it from printing 60.0 sec
|
||||
// when the real value is e.g. 59.91
|
||||
//
|
||||
sprintf(buf, "%s%s%s%s%s", year_buf, day_buf, hour_buf, min_buf, sec_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert nbytes into a string. If total_bytes is non-zero,
|
||||
// convert the two into a fractional display (i.e. 4/16 KB)
|
||||
//
|
||||
void nbytes_to_string(double nbytes, double total_bytes, char* str, int len) {
|
||||
char buf[256];
|
||||
double xTera = (1024.0*1024.0*1024.0*1024.0);
|
||||
double xGiga = (1024.0*1024.0*1024.0);
|
||||
double xMega = (1024.0*1024.0);
|
||||
double xKilo = (1024.0);
|
||||
|
||||
if (total_bytes != 0) {
|
||||
if (total_bytes >= xTera) {
|
||||
sprintf(buf, "%0.2f/%0.2f TB", nbytes/xTera, total_bytes/xTera);
|
||||
} else if (total_bytes >= xGiga) {
|
||||
sprintf(buf, "%0.2f/%0.2f GB", nbytes/xGiga, total_bytes/xGiga);
|
||||
} else if (total_bytes >= xMega) {
|
||||
sprintf(buf, "%0.2f/%0.2f MB", nbytes/xMega, total_bytes/xMega);
|
||||
} else if (total_bytes >= xKilo) {
|
||||
sprintf(buf, "%0.2f/%0.2f KB", nbytes/xKilo, total_bytes/xKilo);
|
||||
} else {
|
||||
sprintf(buf, "%0.0f/%0.0f bytes", nbytes, total_bytes);
|
||||
}
|
||||
} else {
|
||||
if (nbytes >= xTera) {
|
||||
sprintf(buf, "%0.2f TB", nbytes/xTera);
|
||||
} else if (nbytes >= xGiga) {
|
||||
sprintf(buf, "%0.2f GB", nbytes/xGiga);
|
||||
} else if (nbytes >= xMega) {
|
||||
sprintf(buf, "%0.2f MB", nbytes/xMega);
|
||||
} else if (nbytes >= xKilo) {
|
||||
sprintf(buf, "%0.2f KB", nbytes/xKilo);
|
||||
} else {
|
||||
sprintf(buf, "%0.0f bytes", nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
strlcpy(str, buf, len);
|
||||
}
|
||||
|
||||
#define EPOCHFILETIME_SEC (11644473600.)
|
||||
#define TEN_MILLION 10000000.
|
||||
|
||||
|
@ -239,19 +103,6 @@ double dday() {
|
|||
return (now-fmod(now,seconds_per_day));
|
||||
}
|
||||
|
||||
// do sanity check on a time, replace with now if bad
|
||||
// We switched to using all UNIX times on 12/1/04.
|
||||
// During the transition, times in client_state.xml may be
|
||||
// in Windows (1601-based) format. Fix them here.
|
||||
//
|
||||
void validate_time(double& t) {
|
||||
if (t==0) return;
|
||||
double now = dtime();
|
||||
if (t > now+86400*1000) {
|
||||
t -= EPOCHFILETIME_SEC;
|
||||
}
|
||||
}
|
||||
|
||||
// sleep for a specified number of seconds
|
||||
//
|
||||
void boinc_sleep(double seconds) {
|
||||
|
@ -269,127 +120,6 @@ void boinc_sleep(double seconds) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// take a string containing some space separated words.
|
||||
// return an array of pointers to the null-terminated words.
|
||||
// Modifies the string arg.
|
||||
// Returns argc
|
||||
// TODO: use strtok here
|
||||
|
||||
#define NOT_IN_TOKEN 0
|
||||
#define IN_SINGLE_QUOTED_TOKEN 1
|
||||
#define IN_DOUBLE_QUOTED_TOKEN 2
|
||||
#define IN_UNQUOTED_TOKEN 3
|
||||
|
||||
int parse_command_line(char* p, char** argv) {
|
||||
int state = NOT_IN_TOKEN;
|
||||
int argc=0;
|
||||
|
||||
while (*p) {
|
||||
switch(state) {
|
||||
case NOT_IN_TOKEN:
|
||||
if (isspace(*p)) {
|
||||
} else if (*p == '\'') {
|
||||
p++;
|
||||
argv[argc++] = p;
|
||||
state = IN_SINGLE_QUOTED_TOKEN;
|
||||
break;
|
||||
} else if (*p == '\"') {
|
||||
p++;
|
||||
argv[argc++] = p;
|
||||
state = IN_DOUBLE_QUOTED_TOKEN;
|
||||
break;
|
||||
} else {
|
||||
argv[argc++] = p;
|
||||
state = IN_UNQUOTED_TOKEN;
|
||||
}
|
||||
break;
|
||||
case IN_SINGLE_QUOTED_TOKEN:
|
||||
if (*p == '\'') {
|
||||
*p = 0;
|
||||
state = NOT_IN_TOKEN;
|
||||
}
|
||||
break;
|
||||
case IN_DOUBLE_QUOTED_TOKEN:
|
||||
if (*p == '\"') {
|
||||
*p = 0;
|
||||
state = NOT_IN_TOKEN;
|
||||
}
|
||||
break;
|
||||
case IN_UNQUOTED_TOKEN:
|
||||
if (isspace(*p)) {
|
||||
*p = 0;
|
||||
state = NOT_IN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
argv[argc] = 0;
|
||||
return argc;
|
||||
}
|
||||
|
||||
static char x2c(char *what) {
|
||||
register char digit;
|
||||
|
||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
|
||||
digit *= 16;
|
||||
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
|
||||
return(digit);
|
||||
}
|
||||
|
||||
void c2x(char *what) {
|
||||
char buf[3];
|
||||
char num = atoi(what);
|
||||
char d1 = num / 16;
|
||||
char d2 = num % 16;
|
||||
int abase1, abase2;
|
||||
if (d1 < 10) abase1 = 48;
|
||||
else abase1 = 55;
|
||||
if (d2 < 10) abase2 = 48;
|
||||
else abase2 = 55;
|
||||
buf[0] = d1+abase1;
|
||||
buf[1] = d2+abase2;
|
||||
buf[2] = 0;
|
||||
|
||||
strcpy(what, buf);
|
||||
}
|
||||
|
||||
// remove whitespace from start and end of a string
|
||||
//
|
||||
void strip_whitespace(char *str) {
|
||||
int n;
|
||||
while (1) {
|
||||
if (!str[0]) break;
|
||||
if (!isascii(str[0])) break;
|
||||
if (!isspace(str[0])) break;
|
||||
strcpy(str, str+1);
|
||||
}
|
||||
while (1) {
|
||||
n = (int)strlen(str);
|
||||
if (n == 0) break;
|
||||
if (!isascii(str[n-1])) break;
|
||||
if (!isspace(str[n-1])) break;
|
||||
str[n-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void strip_whitespace(string& str) {
|
||||
int n;
|
||||
while (1) {
|
||||
if (str.length() == 0) break;
|
||||
if (!isascii(str[0])) break;
|
||||
if (!isspace(str[0])) break;
|
||||
str.erase(0, 1);
|
||||
}
|
||||
while (1) {
|
||||
n = (int)str.length();
|
||||
if (n == 0) break;
|
||||
if (!isascii(str[n-1])) break;
|
||||
if (!isspace(str[n-1])) break;
|
||||
str.erase(n-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void push_unique(string s, vector<string>& v) {
|
||||
for (unsigned int i=0; i<v.size();i++) {
|
||||
if (s == v[i]) return;
|
||||
|
@ -397,243 +127,6 @@ void push_unique(string s, vector<string>& v) {
|
|||
v.push_back(s);
|
||||
}
|
||||
|
||||
void unescape_url(char *url) {
|
||||
int x,y;
|
||||
|
||||
for (x=0,y=0;url[y];++x,++y) {
|
||||
if ((url[x] = url[y]) == '%') {
|
||||
url[x] = x2c(&url[y+1]);
|
||||
y+=2;
|
||||
}
|
||||
}
|
||||
url[x] = '\0';
|
||||
}
|
||||
|
||||
void unescape_url_safe(char *url, int url_size) {
|
||||
int x,y;
|
||||
|
||||
for (x=0,y=0; url[y] && (x<url_size);++x,++y) {
|
||||
if ((url[x] = url[y]) == '%') {
|
||||
url[x] = x2c(&url[y+1]);
|
||||
y+=2;
|
||||
}
|
||||
}
|
||||
url[x] = '\0';
|
||||
}
|
||||
|
||||
// unescape_url needs to be able to handle potentially hostile
|
||||
// urls.
|
||||
void unescape_url(string& url) {
|
||||
char buf[1024];
|
||||
strncpy(buf, url.c_str(), sizeof(buf));
|
||||
unescape_url_safe(buf, sizeof(buf));
|
||||
url = buf;
|
||||
}
|
||||
|
||||
void escape_url(char *in, char*out) {
|
||||
int x, y;
|
||||
for (x=0, y=0; in[x]; ++x) {
|
||||
if (isalnum(in[x])) {
|
||||
out[y] = in[x];
|
||||
++y;
|
||||
} else {
|
||||
out[y] = '%';
|
||||
++y;
|
||||
out[y] = 0;
|
||||
char buf[256];
|
||||
sprintf(buf, "%d", (char)in[x]);
|
||||
c2x(buf);
|
||||
strcat(out, buf);
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
out[y] = 0;
|
||||
}
|
||||
|
||||
void escape_url_safe(const char *in, char*out, int out_size) {
|
||||
int x, y;
|
||||
for (x=0, y=0; in[x] && (y<out_size); ++x) {
|
||||
if (isalnum(in[x])) {
|
||||
out[y] = in[x];
|
||||
++y;
|
||||
} else {
|
||||
out[y] = '%';
|
||||
++y;
|
||||
out[y] = 0;
|
||||
char buf[256];
|
||||
sprintf(buf, "%d", (char)in[x]);
|
||||
c2x(buf);
|
||||
strcat(out, buf);
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
out[y] = 0;
|
||||
}
|
||||
|
||||
// escape_url needs to be able to handle potentially hostile
|
||||
// urls
|
||||
void escape_url(string& url) {
|
||||
char buf[1024];
|
||||
escape_url_safe(url.c_str(), buf, sizeof(buf));
|
||||
url = buf;
|
||||
}
|
||||
|
||||
// Escape a URL for the project directory, cutting off the "http://",
|
||||
// converting '\' '/' and ' ' to '_',
|
||||
// and converting the non alphanumeric characters to %XY
|
||||
// where XY is their hexadecimal equivalent
|
||||
//
|
||||
void escape_url_readable(char *in, char* out) {
|
||||
int x, y;
|
||||
char *temp;
|
||||
|
||||
temp = strstr(in,"://");
|
||||
if (temp) {
|
||||
in = temp + strlen("://");
|
||||
}
|
||||
for (x=0, y=0; in[x]; ++x) {
|
||||
if (isalnum(in[x]) || in[x]=='.' || in[x]=='-' || in[x]=='_') {
|
||||
out[y] = in[x];
|
||||
++y;
|
||||
} else {
|
||||
out[y] = '_';
|
||||
++y;
|
||||
}
|
||||
}
|
||||
out[y] = 0;
|
||||
}
|
||||
|
||||
|
||||
// Canonicalize a master url.
|
||||
// - Convert the first part of a URL (before the "://") to http://,
|
||||
// or prepend it
|
||||
// - Remove double slashes in the rest
|
||||
// - Add a trailing slash if necessary
|
||||
//
|
||||
void canonicalize_master_url(char* url) {
|
||||
char buf[1024];
|
||||
size_t n;
|
||||
bool bSSL = false; // keep track if they sent in https://
|
||||
|
||||
char *p = strstr(url, "://");
|
||||
if (p) {
|
||||
bSSL = (bool) (p == url + 5);
|
||||
strcpy(buf, p+3);
|
||||
} else {
|
||||
strcpy(buf, url);
|
||||
}
|
||||
while (1) {
|
||||
p = strstr(buf, "//");
|
||||
if (!p) break;
|
||||
strcpy(p, p+1);
|
||||
}
|
||||
n = strlen(buf);
|
||||
if (buf[n-1] != '/') {
|
||||
strcat(buf, "/");
|
||||
}
|
||||
sprintf(url, "http%s://%s", (bSSL ? "s" : ""), buf); // CMC Here -- add SSL if needed
|
||||
}
|
||||
|
||||
void canonicalize_master_url(string& url) {
|
||||
char buf[1024];
|
||||
strcpy(buf, url.c_str());
|
||||
canonicalize_master_url(buf);
|
||||
url = buf;
|
||||
}
|
||||
|
||||
// is the string a valid master URL, in canonical form?
|
||||
//
|
||||
bool valid_master_url(char* buf) {
|
||||
char* p, *q;
|
||||
size_t n;
|
||||
bool bSSL = false;
|
||||
|
||||
p = strstr(buf, "http://");
|
||||
if (p != buf) {
|
||||
// allow https
|
||||
p = strstr(buf, "https://");
|
||||
if (p == buf) {
|
||||
bSSL = true;
|
||||
} else {
|
||||
return false; // no http or https, it's bad!
|
||||
}
|
||||
}
|
||||
q = p+strlen(bSSL ? "https://" : "http://");
|
||||
p = strstr(q, ".");
|
||||
if (!p) return false;
|
||||
if (p == q) return false;
|
||||
q = p+1;
|
||||
p = strstr(q, "/");
|
||||
if (!p) return false;
|
||||
if (p == q) return false;
|
||||
n = strlen(buf);
|
||||
if (buf[n-1] != '/') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
char* time_to_string(double t) {
|
||||
static char buf[100];
|
||||
time_t x = (time_t)t;
|
||||
struct tm* tm = localtime(&x);
|
||||
strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char* precision_time_to_string(double t) {
|
||||
static char buf[100];
|
||||
char finer[16];
|
||||
int hundreds_of_microseconds=(int)(10000*(t-(int)t));
|
||||
if (hundreds_of_microseconds == 10000) {
|
||||
// paranoia -- this should never happen!
|
||||
//
|
||||
hundreds_of_microseconds=0;
|
||||
t+=1.0;
|
||||
}
|
||||
time_t x = (time_t)t;
|
||||
struct tm* tm = localtime(&x);
|
||||
|
||||
strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm);
|
||||
sprintf(finer, ".%04d", hundreds_of_microseconds);
|
||||
strcat(buf, finer);
|
||||
return buf;
|
||||
}
|
||||
|
||||
string timediff_format(double diff) {
|
||||
char buf[256];
|
||||
int tdiff = (int)diff;
|
||||
|
||||
int sex = tdiff % 60;
|
||||
tdiff /= 60;
|
||||
if (!tdiff) {
|
||||
sprintf(buf, "%d sec", sex);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int min = tdiff % 60;
|
||||
tdiff /= 60;
|
||||
if (!tdiff) {
|
||||
sprintf(buf, "%d min %d sec", min, sex);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int hours = tdiff % 24;
|
||||
tdiff /= 24;
|
||||
if (!tdiff) {
|
||||
sprintf(buf, "%d hr %d min %d sec", hours, min, sex);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int days = tdiff % 7;
|
||||
tdiff /= 7;
|
||||
if (!tdiff) {
|
||||
sprintf(buf, "%d days %d hr %d min %d sec", days, hours, min, sex);
|
||||
return buf;
|
||||
}
|
||||
|
||||
sprintf(buf, "%d weeks %d days %d hrs %d min %d sec", (int)tdiff, days, hours, min, sex);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// read entire file into string
|
||||
int read_file_string(const char* pathname, string& result) {
|
||||
result.erase();
|
||||
|
@ -904,180 +397,6 @@ void update_average(
|
|||
avg_time = now;
|
||||
}
|
||||
|
||||
void escape_project_url(char *in, char* out) {
|
||||
escape_url_readable(in, out);
|
||||
char& last = out[strlen(out)-1];
|
||||
// remove trailing _
|
||||
if (last == '_') {
|
||||
last = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void mysql_timestamp(double dt, char* p) {
|
||||
struct tm* tmp;
|
||||
time_t t = (time_t)dt;
|
||||
tmp = localtime(&t); // MySQL timestamps are in local time
|
||||
sprintf(p, "%4d%02d%02d%02d%02d%02d",
|
||||
tmp->tm_year+1900, tmp->tm_mon+1, tmp->tm_mday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec
|
||||
);
|
||||
}
|
||||
|
||||
// Return a text-string description of a given error.
|
||||
// Must be kept consistent with error_numbers.h
|
||||
//
|
||||
const char* boincerror(int which_error) {
|
||||
switch (which_error) {
|
||||
case BOINC_SUCCESS: return "Success";
|
||||
case ERR_SELECT: return "system select";
|
||||
case ERR_MALLOC: return "system malloc";
|
||||
case ERR_READ: return "system read";
|
||||
case ERR_WRITE: return "system write";
|
||||
case ERR_FREAD: return "system fread";
|
||||
case ERR_FWRITE: return "system fwrite";
|
||||
case ERR_IO: return "system I/O";
|
||||
case ERR_CONNECT: return "system connect";
|
||||
case ERR_FOPEN: return "system fopen";
|
||||
case ERR_RENAME: return "system rename";
|
||||
case ERR_UNLINK: return "system unlink";
|
||||
case ERR_OPENDIR: return "system opendir";
|
||||
case ERR_XML_PARSE: return "unexpected XML tag or syntax";
|
||||
case ERR_GETHOSTBYNAME: return "can't resolve hostname";
|
||||
case ERR_GIVEUP_DOWNLOAD: return "timeout on download";
|
||||
case ERR_GIVEUP_UPLOAD: return "timeout on upload";
|
||||
case ERR_NULL: return "null pointer";
|
||||
case ERR_NEG: return "unexpected negative value";
|
||||
case ERR_BUFFER_OVERFLOW: return "buffer overflow";
|
||||
case ERR_MD5_FAILED: return "md5 checksum failed for file";
|
||||
case ERR_RSA_FAILED: return "RSA key check failed for file";
|
||||
case ERR_OPEN: return "system open";
|
||||
case ERR_DUP2: return "system dup";
|
||||
case ERR_NO_SIGNATURE: return "no signature";
|
||||
case ERR_THREAD: return "creating a thread";
|
||||
case ERR_SIGNAL_CATCH: return "caught signal";
|
||||
case ERR_UPLOAD_TRANSIENT: return "transient upload error";
|
||||
case ERR_UPLOAD_PERMANENT: return "fatal upload error";
|
||||
case ERR_IDLE_PERIOD: return "user preferences say can't start work";
|
||||
case ERR_ALREADY_ATTACHED: return "already attached to project";
|
||||
case ERR_FILE_TOO_BIG: return "file size too big";
|
||||
case ERR_GETRUSAGE: return "system getrusage";
|
||||
case ERR_BENCHMARK_FAILED: return "benchmark failed";
|
||||
case ERR_BAD_HEX_FORMAT: return "hex format key data bad";
|
||||
case ERR_DB_NOT_FOUND: return "no database rows found in lookup/enumerate";
|
||||
case ERR_DB_NOT_UNIQUE: return "database lookup not unique";
|
||||
case ERR_DB_CANT_CONNECT: return "can't connect to datbase";
|
||||
case ERR_GETS: return "system gets/fgets";
|
||||
case ERR_SCANF: return "system scanf/fscanf";
|
||||
case ERR_READDIR: return "system readdir";
|
||||
case ERR_SHMGET: return "system shmget";
|
||||
case ERR_SHMCTL: return "system shmctl";
|
||||
case ERR_SHMAT: return "system shmat";
|
||||
case ERR_FORK: return "system fork";
|
||||
case ERR_EXEC: return "system exec";
|
||||
case ERR_NOT_EXITED: return "process didn't exit";
|
||||
case ERR_NOT_IMPLEMENTED: return "system call not implemented";
|
||||
case ERR_GETHOSTNAME: return "system gethostname";
|
||||
case ERR_NETOPEN: return "system netopen";
|
||||
case ERR_SOCKET: return "system socket";
|
||||
case ERR_FCNTL: return "system fcntl";
|
||||
case ERR_AUTHENTICATOR: return "authentication error";
|
||||
case ERR_SCHED_SHMEM: return "scheduler shared memory contents bad";
|
||||
case ERR_ASYNCSELECT: return "system async select";
|
||||
case ERR_BAD_RESULT_STATE: return "bad result state";
|
||||
case ERR_DB_CANT_INIT: return "can't init database";
|
||||
case ERR_NOT_UNIQUE: return "state files have redundant entries";
|
||||
case ERR_NOT_FOUND: return "not found";
|
||||
case ERR_NO_EXIT_STATUS: return "no exit status in scheduler request";
|
||||
case ERR_FILE_MISSING: return "file missing";
|
||||
case ERR_SEMGET: return "system get semaphore";
|
||||
case ERR_SEMCTL: return "system control semaphore";
|
||||
case ERR_SEMOP: return "system op semaphore";
|
||||
case ERR_FTOK: return "system ftok";
|
||||
case ERR_SOCKS_UNKNOWN_FAILURE: return "socket unknown";
|
||||
case ERR_SOCKS_REQUEST_FAILED: return "socket request";
|
||||
case ERR_SOCKS_BAD_USER_PASS: return "socket bad user password";
|
||||
case ERR_SOCKS_UNKNOWN_SERVER_VERSION: return "socket unknown server version";
|
||||
case ERR_SOCKS_UNSUPPORTED: return "socket unsupported";
|
||||
case ERR_SOCKS_CANT_REACH_HOST: return "socket can't reach host";
|
||||
case ERR_SOCKS_CONN_REFUSED: return "socket connection refused";
|
||||
case ERR_TIMER_INIT: return "timer init";
|
||||
case ERR_RSC_LIMIT_EXCEEDED: return "resource limit exceeded";
|
||||
case ERR_INVALID_PARAM: return "invalid parameter";
|
||||
case ERR_SIGNAL_OP: return "signal op";
|
||||
case ERR_BIND: return "system bind";
|
||||
case ERR_LISTEN: return "system listen";
|
||||
case ERR_TIMEOUT: return "timeout";
|
||||
case ERR_PROJECT_DOWN: return "project down";
|
||||
case ERR_HTTP_ERROR: return "http error";
|
||||
case ERR_RESULT_START: return "result start";
|
||||
case ERR_RESULT_DOWNLOAD: return "result download";
|
||||
case ERR_RESULT_UPLOAD: return "result upload";
|
||||
case ERR_INVALID_URL: return "invalid URL";
|
||||
case ERR_MAJOR_VERSION: return "major version";
|
||||
case ERR_NO_OPTION: return "no option";
|
||||
case ERR_MKDIR: return "mkdir";
|
||||
case ERR_INVALID_EVENT: return "invalid event";
|
||||
case ERR_ALREADY_RUNNING: return "already running";
|
||||
case ERR_NO_APP_VERSION: return "no app version";
|
||||
case ERR_WU_USER_RULE: return "user already did result for this workunit";
|
||||
case ERR_ABORTED_VIA_GUI: return "result aborted via GUI";
|
||||
case ERR_INSUFFICIENT_RESOURCE: return "insufficient resources";
|
||||
case ERR_RETRY: return "retry";
|
||||
case ERR_WRONG_SIZE: return "wrong size";
|
||||
case ERR_USER_PERMISSION: return "user permission";
|
||||
case ERR_BAD_EMAIL_ADDR: return "bad email address";
|
||||
case ERR_BAD_PASSWD: return "bad password";
|
||||
case ERR_SHMEM_NAME: return "can't get shared mem segment name";
|
||||
case ERR_NO_NETWORK_CONNECTION: return "no available network connection";
|
||||
case ERR_ATTACH_FAIL_INIT: return "Couldn't start master page download";
|
||||
case ERR_ATTACH_FAIL_DOWNLOAD: return "Couldn't download master page";
|
||||
case ERR_ATTACH_FAIL_PARSE: return "Couldn't parse master page";
|
||||
case ERR_ATTACH_FAIL_BAD_KEY: return "Invalid account key";
|
||||
case ERR_ATTACH_FAIL_FILE_WRITE: return "Couldn't write account file";
|
||||
case ERR_FFLUSH: return "Couldn't flush file";
|
||||
case ERR_FSYNC: return "Couldn't sync file";
|
||||
case ERR_TRUNCATE: return "Couldn't truncate file";
|
||||
case ERR_ABORTED_BY_PROJECT: return "Aborted by project";
|
||||
case ERR_GETGRNAM: return "Group not found";
|
||||
case ERR_CHOWN: return "can't change owner";
|
||||
case ERR_FILE_NOT_FOUND: return "file not found";
|
||||
case 404: return "HTTP file not found";
|
||||
case 407: return "HTTP proxy authentication failure";
|
||||
case 416: return "HTTP range request error";
|
||||
case 500: return "HTTP internal server error";
|
||||
case 501: return "HTTP not implemented";
|
||||
case 502: return "HTTP bad gateway";
|
||||
case 503: return "HTTP service unavailable";
|
||||
case 504: return "HTTP gateway timeout";
|
||||
}
|
||||
static char buf[128];
|
||||
sprintf(buf, "Error %d", which_error);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char* network_status_string(int n) {
|
||||
switch (n) {
|
||||
case NETWORK_STATUS_ONLINE: return "online";
|
||||
case NETWORK_STATUS_WANT_CONNECTION: return "need connection";
|
||||
case NETWORK_STATUS_WANT_DISCONNECT: return "don't need connection";
|
||||
case NETWORK_STATUS_LOOKUP_PENDING: return "reference site lookup pending";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* rpc_reason_string(int reason) {
|
||||
switch (reason) {
|
||||
case RPC_REASON_USER_REQ: return "Requested by user";
|
||||
case RPC_REASON_NEED_WORK: return "To fetch work";
|
||||
case RPC_REASON_RESULTS_DUE: return "To report completed tasks";
|
||||
case RPC_REASON_TRICKLE_UP: return "To send trickle-up message";
|
||||
case RPC_REASON_ACCT_MGR_REQ: return "Requested by account manager";
|
||||
case RPC_REASON_INIT: return "Project initialization";
|
||||
case RPC_REASON_PROJECT_REQ: return "Requested by project";
|
||||
default: return "Unknown reason";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
int lookup_group(char* name, gid_t& gid) {
|
||||
struct group* gp = getgrnam(name);
|
||||
|
|
58
lib/util.h
58
lib/util.h
|
@ -42,67 +42,16 @@
|
|||
extern int g_use_sandbox;
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_STRLCPY)
|
||||
extern size_t strlcpy(char*, const char*, size_t);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRLCAT)
|
||||
extern size_t strlcat(char *dst, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
extern int ndays_to_string(double x, int smallest_timescale, char *buf);
|
||||
extern void nbytes_to_string(double nbytes, double total_bytes, char* str, int len);
|
||||
extern double dtime();
|
||||
extern double dday();
|
||||
extern void validate_time(double&);
|
||||
extern void boinc_sleep(double);
|
||||
extern int parse_command_line( char *, char ** );
|
||||
extern void c2x(char *what);
|
||||
extern void strip_whitespace(char *str);
|
||||
extern void strip_whitespace(std::string&);
|
||||
extern void unescape_url(std::string& url);
|
||||
extern void unescape_url(char *url);
|
||||
extern void escape_url(std::string& url);
|
||||
extern void escape_url(char *in, char*out);
|
||||
extern void escape_url_readable(char* in, char* out);
|
||||
extern bool valid_master_url(char*);
|
||||
extern void canonicalize_master_url(char *url);
|
||||
extern void canonicalize_master_url(std::string&);
|
||||
#define safe_strcpy(x, y) strlcpy(x, y, sizeof(x))
|
||||
#define safe_strcat(x, y) if (strlen(x)+strlen(y)<sizeof(x)) strcat(x, y)
|
||||
extern char* time_to_string(double);
|
||||
extern char* precision_time_to_string(double);
|
||||
extern std::string timediff_format(double);
|
||||
extern int read_file_string(const char* pathname, std::string& result);
|
||||
extern void escape_project_url(char *in, char* out);
|
||||
extern void push_unique(std::string, std::vector<std::string>&);
|
||||
|
||||
inline bool ends_with(std::string const& s, std::string const& suffix) {
|
||||
return
|
||||
s.size()>=suffix.size() &&
|
||||
s.substr(s.size()-suffix.size()) == suffix;
|
||||
}
|
||||
|
||||
inline bool starts_with(std::string const& s, std::string const& prefix) {
|
||||
return s.substr(0, prefix.size()) == prefix;
|
||||
}
|
||||
|
||||
// http://lists.debian.org/debian-gcc/2002/debian-gcc-200204/msg00092.html
|
||||
inline void downcase_string(
|
||||
std::string::iterator begin, std::string::iterator end, std::string::iterator src
|
||||
) {
|
||||
std::transform(begin, end, src, (int(*)(int))tolower);
|
||||
}
|
||||
|
||||
inline void downcase_string(std::string& w) {
|
||||
downcase_string(w.begin(), w.end(), w.begin());
|
||||
}
|
||||
|
||||
// NOTE: use #include <functional> to get max,min
|
||||
|
||||
#define SECONDS_PER_DAY 86400
|
||||
#define MEGA (1048576.0)
|
||||
|
||||
static inline double drand() {
|
||||
return (double)rand()/(double)RAND_MAX;
|
||||
|
@ -129,13 +78,6 @@ extern int boinc_calling_thread_cpu_time(double&);
|
|||
//
|
||||
extern void mysql_timestamp(double, char*);
|
||||
|
||||
// returns short text description of error corresponding to
|
||||
// int errornumber from error_numbers.h
|
||||
//
|
||||
extern const char* boincerror(int which_error);
|
||||
extern const char* network_status_string(int);
|
||||
extern const char* rpc_reason_string(int);
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
extern pthread_mutex_t getrusage_mutex;
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "boinc_db.h"
|
||||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
#include "strings.h"
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ using namespace std;
|
|||
#include "backend_lib.h"
|
||||
#include "error_numbers.h"
|
||||
#include "parse.h"
|
||||
#include "str_util.h"
|
||||
#include "util.h"
|
||||
#include "filesys.h"
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "boinc_db.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
|
||||
#include "main.h"
|
||||
|
|
|
@ -34,6 +34,7 @@ using namespace std;
|
|||
#include "error_numbers.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
|
||||
#include "server_types.h"
|
||||
#include "sched_shmem.h"
|
||||
|
|
|
@ -24,7 +24,7 @@ using namespace std;
|
|||
|
||||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "main.h"
|
||||
#include "sched_util.h"
|
||||
#include "sched_msgs.h"
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "error_numbers.h"
|
||||
#include "md5_file.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "str_util.h"
|
||||
#include "filesys.h"
|
||||
#include "sched_util.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue