diff --git a/client/app.cpp b/client/app.cpp
index de2ebca81f..e5f5e10bbf 100644
--- a/client/app.cpp
+++ b/client/app.cpp
@@ -298,6 +298,11 @@ void procinfo_show(PROCINFO& pi, PROC_MAP& pm) {
}
#endif
+// scan the set of all processes to
+// 1) get the working-set size of active tasks
+// 2) see if exclusive apps are running
+// 3) get CPU time of non-BOINC processes
+//
void ACTIVE_TASK_SET::get_memory_usage() {
static double last_mem_time=0;
unsigned int i;
@@ -350,7 +355,14 @@ void ACTIVE_TASK_SET::get_memory_usage() {
v = &(atp->other_pids);
}
procinfo_app(pi, v, pm, atp->app_version->graphics_exec_file);
- pi.working_set_size_smoothed = .5*(pi.working_set_size_smoothed + pi.working_set_size);
+ if (atp->app_version->is_vm_app) {
+ // the memory of virtual machine apps is not reported correctly,
+ // at least on Windows. Use the VM size instead.
+ //
+ pi.working_set_size_smoothed = atp->wup->rsc_memory_bound;
+ } else {
+ pi.working_set_size_smoothed = .5*(pi.working_set_size_smoothed + pi.working_set_size);
+ }
if (!first) {
int pf = pi.page_fault_count - last_page_fault_count;
@@ -1031,4 +1043,4 @@ void* throttler(void*) {
}
return 0;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/client/client_types.cpp b/client/client_types.cpp
index 10437e92a4..402b80e9af 100644
--- a/client/client_types.cpp
+++ b/client/client_types.cpp
@@ -745,6 +745,7 @@ void APP_VERSION::init() {
strcpy(missing_coproc_name, "");
dont_throttle = false;
needs_network = false;
+ is_vm_app = false;
}
int APP_VERSION::parse(XML_PARSER& xp) {
@@ -786,6 +787,9 @@ int APP_VERSION::parse(XML_PARSER& xp) {
}
}
}
+ if (strstr(plan_class, "vbox")) {
+ is_vm_app = true;
+ }
return 0;
}
if (xp.parse_str("app_name", app_name, sizeof(app_name))) continue;
diff --git a/client/client_types.h b/client/client_types.h
index d26f2035fc..8a27c54262 100644
--- a/client/client_types.h
+++ b/client/client_types.h
@@ -306,6 +306,7 @@ struct APP_VERSION {
double missing_coproc_usage;
char missing_coproc_name[256];
bool dont_throttle;
+ bool is_vm_app;
int index; // temp var for make_scheduler_request()
#ifdef SIM
diff --git a/db/boinc_db_types.h b/db/boinc_db_types.h
index 9ca17825df..7f4b010efa 100644
--- a/db/boinc_db_types.h
+++ b/db/boinc_db_types.h
@@ -638,19 +638,6 @@ struct BATCH {
// Condor calls this the batch's "lease".
};
-// values of batch.state
-// see html/inc/common_defs.inc
-//
-#define BATCH_STATE_INIT 0
-#define BATCH_STATE_IN_PROGRESS 1
-#define BATCH_STATE_COMPLETE 2
- // "complete" means all workunits have either
- // a canonical result or an error
-#define BATCH_STATE_ABORTED 3
-#define BATCH_STATE_RETIRED 4
- // input/output files can be deleted,
- // result and workunit records can be purged.
-
// info for users who can submit jobs
//
struct USER_SUBMIT {
diff --git a/doc/projects.inc b/doc/projects.inc
index d5ed3c4c10..27a0c35be4 100644
--- a/doc/projects.inc
+++ b/doc/projects.inc
@@ -407,7 +407,7 @@ $math = array(
array(
"SAT@home",
"http://sat.isa.ru/pdsat/",
- "Institute for Systems Analysis and Institute for System Dynamics and Control Theory, Russian Academy of Science",
+ "Institute for System Dynamics and Control Theory and Institute for Information Transmission Problems, Russian Academy of Science",
"Computer Science",
"Solve hard and practically important problems (discrete functions inversion problems, discrete optimization, bioinformatics, etc.) that can be effectively reduced to Boolean satisfiability problem.",
"sat_logo.png"
diff --git a/html/user/submit_rpc_handler.php b/html/user/submit_rpc_handler.php
index 169e690159..0487b04ee4 100644
--- a/html/user/submit_rpc_handler.php
+++ b/html/user/submit_rpc_handler.php
@@ -350,6 +350,7 @@ function query_batch($r) {
foreach ($wus as $wu) {
echo "
$wu->id
+ $wu->name
$wu->canonical_resultid
$n_outfiles
diff --git a/lib/common_defs.h b/lib/common_defs.h
index 4134bd6546..fdd385d994 100644
--- a/lib/common_defs.h
+++ b/lib/common_defs.h
@@ -194,6 +194,19 @@ enum BATTERY_STATE {
#define RPC_REASON_INIT 6
#define RPC_REASON_PROJECT_REQ 7
+// values of batch.state
+// see html/inc/common_defs.inc
+//
+#define BATCH_STATE_INIT 0
+#define BATCH_STATE_IN_PROGRESS 1
+#define BATCH_STATE_COMPLETE 2
+ // "complete" means all workunits have either
+ // a canonical result or an error
+#define BATCH_STATE_ABORTED 3
+#define BATCH_STATE_RETIRED 4
+ // input/output files can be deleted,
+ // result and workunit records can be purged.
+
struct TIME_STATS {
// we maintain an exponentially weighted average of these quantities:
double now;
diff --git a/lib/remote_submit.cpp b/lib/remote_submit.cpp
index 8484d204c9..e118734d07 100644
--- a/lib/remote_submit.cpp
+++ b/lib/remote_submit.cpp
@@ -28,6 +28,7 @@
#include
#include "parse.h"
+#include "str_util.h"
#include "url.h"
#include "remote_submit.h"
@@ -203,7 +204,6 @@ int upload_files (
return retval;
}
fseek(reply, 0, SEEK_SET);
- bool success = false;
retval = -1;
error_msg = "";
while (fgets(buf, 256, reply)) {
@@ -310,7 +310,6 @@ int estimate_batch(
fseek(reply, 0, SEEK_SET);
retval = -1;
error_msg = "";
- int temp;
while (fgets(buf, 256, reply)) {
#ifdef SHOW_REPLY
printf("submit_batch reply: %s", buf);
@@ -395,11 +394,11 @@ int submit_jobs(
return retval;
}
-int query_batches(
+int query_batch_set(
const char* project_url,
const char* authenticator,
vector &batch_names,
- QUERY_BATCH_REPLY& qb_reply,
+ QUERY_BATCH_SET_REPLY& qb_reply,
string& error_msg
) {
string request;
@@ -440,17 +439,17 @@ int query_batches(
continue;
}
if (strstr(buf, "")) {
- QUERY_BATCH_JOB qbj;
+ JOB_STATUS js;
while (fgets(buf, 256, reply)) {
#ifdef SHOW_REPLY
printf("query_batches reply: %s", buf);
#endif
if (strstr(buf, "")) {
- qb_reply.jobs.push_back(qbj);
+ qb_reply.jobs.push_back(js);
break;
}
- if (parse_str(buf, "job_name", qbj.job_name)) continue;
- if (parse_str(buf, "status", qbj.status)) continue;
+ if (parse_str(buf, "job_name", js.job_name)) continue;
+ if (parse_str(buf, "status", js.status)) continue;
}
continue;
}
@@ -459,6 +458,187 @@ int query_batches(
return retval;
}
+int BATCH_STATUS::parse(XML_PARSER& xp) {
+ memset(this, 0, sizeof(BATCH_STATUS));
+ while (!xp.get_tag()) {
+ if (xp.match_tag("/batch")) {
+ return 0;
+ }
+ if (xp.parse_int("id", id)) continue;
+ if (xp.parse_str("name", name, sizeof(name))) continue;
+ if (xp.parse_int("state", state)) continue;
+ if (xp.parse_int("njobs", njobs)) continue;
+ if (xp.parse_int("nerror_jobs", nerror_jobs)) continue;
+ if (xp.parse_double("fraction_done", fraction_done)) continue;
+ if (xp.parse_double("create_time", create_time)) continue;
+ if (xp.parse_double("expire_time", expire_time)) continue;
+ if (xp.parse_double("est_completion_time", est_completion_time)) continue;
+ if (xp.parse_double("completion_time", completion_time)) continue;
+ if (xp.parse_double("credit_estimate", credit_estimate)) continue;
+ if (xp.parse_double("credit_canonical", credit_canonical)) continue;
+ }
+ return ERR_XML_PARSE;
+}
+
+void BATCH_STATUS::print() {
+ printf("Batch %d (%s)\n"
+ " state: %s\n"
+ " njobs: %d\n"
+ " nerror_jobs: %d\n"
+ " fraction_done: %f\n",
+ id, name,
+ batch_state_string(state),
+ njobs,
+ nerror_jobs,
+ fraction_done
+ );
+ printf(
+ " create_time: %s\n",
+ time_to_string(create_time)
+ );
+ printf(
+ " expire_time: %s\n",
+ time_to_string(expire_time)
+ );
+ printf(
+ " est_completion_time: %s\n",
+ time_to_string(est_completion_time)
+ );
+ printf(
+ " completion_time: %s\n",
+ time_to_string(completion_time)
+ );
+ printf(
+ " credit_estimate: %f\n"
+ " credit_canonical: %f\n",
+ credit_estimate,
+ credit_canonical
+ );
+}
+
+int query_batches(
+ const char* project_url,
+ const char* authenticator,
+ vector& batches,
+ string &error_msg
+) {
+ string request;
+ char url[1024], buf[256];
+ request = "\n";
+ sprintf(buf, "%s\n", authenticator);
+ request += string(buf);
+ request += "\n";
+ sprintf(url, "%ssubmit_rpc_handler.php", project_url);
+ FILE* reply = tmpfile();
+ vector x;
+ int retval = do_http_post(url, request.c_str(), reply, x);
+ if (retval) {
+ fclose(reply);
+ return retval;
+ }
+ fseek(reply, 0, SEEK_SET);
+ retval = -1;
+ error_msg = "failed to parse Web RPC reply";
+ MIOFILE mf;
+ XML_PARSER xp(&mf);
+ mf.init_file(reply);
+ while (!xp.get_tag()) {
+ if (xp.match_tag("/batches")) {
+ retval = 0;
+ error_msg = "";
+ break;
+ }
+ if (xp.match_tag("batch")) {
+ BATCH_STATUS bs;
+ if (!bs.parse(xp)) {
+ batches.push_back(bs);
+ }
+ continue;
+ }
+ if (xp.parse_string("error_msg", error_msg)) continue;
+ if (xp.parse_int("error_num", retval)) continue;
+ }
+ fclose(reply);
+ return retval;
+}
+
+int JOB_STATE::parse(XML_PARSER& xp) {
+ memset(this, 0, sizeof(JOB_STATE));
+ while (!xp.get_tag()) {
+ if (xp.match_tag("/job")) {
+ return 0;
+ }
+ if (xp.parse_int("id", id)) continue;
+ if (xp.parse_str("name", name, sizeof(name))) continue;
+ if (xp.parse_int("canonical_instance_id", canonical_instance_id)) continue;
+ if (xp.parse_int("n_outfiles", n_outfiles)) continue;
+ }
+ return ERR_XML_PARSE;
+}
+
+void JOB_STATE::print() {
+ printf(
+ "job %d (%s)\n"
+ " canonical_instance_id %d\n"
+ " n_outfiles %d\n",
+ id, name,
+ canonical_instance_id,
+ n_outfiles
+ );
+}
+
+int query_batch(
+ const char* project_url,
+ const char* authenticator,
+ int batch_id,
+ const char* batch_name,
+ vector& jobs,
+ string &error_msg
+) {
+ string request;
+ char url[1024], buf[256];
+ request = "\n";
+ sprintf(buf, "%s\n", authenticator);
+ request += string(buf);
+ if (batch_id) {
+ sprintf(buf, "%d\n", batch_id);
+ } else {
+ sprintf(buf, "%s\n", batch_name);
+ }
+ request += string(buf);
+ request += "\n";
+ sprintf(url, "%ssubmit_rpc_handler.php", project_url);
+ FILE* reply = tmpfile();
+ vector x;
+ int retval = do_http_post(url, request.c_str(), reply, x);
+ if (retval) {
+ fclose(reply);
+ return retval;
+ }
+ fseek(reply, 0, SEEK_SET);
+ retval = -1;
+ error_msg = "";
+ MIOFILE mf;
+ XML_PARSER xp(&mf);
+ mf.init_file(reply);
+ while (!xp.get_tag()) {
+ if (xp.match_tag("/jobs")) {
+ retval = 0;
+ break;
+ }
+ if (xp.match_tag("job")) {
+ JOB_STATE js;
+ if (!js.parse(xp)) {
+ jobs.push_back(js);
+ }
+ continue;
+ }
+
+ }
+ fclose(reply);
+ return retval;
+}
+
int abort_jobs(
const char* project_url,
const char* authenticator,
@@ -551,7 +731,6 @@ int get_templates(
}
int TEMPLATE_DESC::parse(XML_PARSER& xp) {
- int retval;
string s;
while (!xp.get_tag()) {
if (xp.match_tag("input_template")) {
diff --git a/lib/remote_submit.h b/lib/remote_submit.h
index 6195815188..d6bf903344 100644
--- a/lib/remote_submit.h
+++ b/lib/remote_submit.h
@@ -18,11 +18,16 @@
// C++ interfaces to remote job submission and file management RPCs
// See http://boinc.berkeley.edu/trac/wiki/RemoteJobs#Cinterface
+#ifndef REMOTE_SUBMIT_H
+#define REMOTE_SUBMIT_H
+
#include
#include
#include
#include