From 6971fddbde1a6a87247ea97a343c79d0f63336cb Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 3 May 2005 21:50:51 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=6003 --- checkin_notes | 17 +++++ db/boinc_db.C | 155 +++++++++++++++++++++++++++++++++++++++++ db/boinc_db.h | 2 +- doc/credit.php | 32 +++++---- sched/handle_request.C | 12 ++-- sched/server_types.C | 9 +-- 6 files changed, 203 insertions(+), 24 deletions(-) diff --git a/checkin_notes b/checkin_notes index 2e98fa88b9..28e19a1779 100755 --- a/checkin_notes +++ b/checkin_notes @@ -5982,3 +5982,20 @@ Rom 3 May 2005 clientgui/ ViewStatistics.cpp + +David 3 May 2005 + - scheduler: fixed a bug where host::update() + could potentially overwrite a credit update + happening around the same time. + Did this by adding a function HOST::update_diff(HOST& initial) + which does an update only of those fields that have + changed relative to the given initial values. + (from Bruce Allen) + - removed unused "p_calculated" from HOST + - removed code to parse non-existent fields p_fpop_err etc. in HOST + + db/ + boinc_db.C,h + sched/ + handle_request.C + server_types.C diff --git a/db/boinc_db.C b/db/boinc_db.C index 319dd4e597..ca6e476802 100644 --- a/db/boinc_db.C +++ b/db/boinc_db.C @@ -409,6 +409,161 @@ void DB_HOST::db_parse(MYSQL_ROW &r) { max_results_day = atoi(r[i++]); } +// update fields that differ from the argument HOST +// +int DB_HOST::update_diff(HOST& h) { + char buf[LARGE_BLOB_SIZE], updates[LARGE_BLOB_SIZE], query[LARGE_BLOB_SIZE]; + strcpy(updates, ""); + if (rpc_seqno != h.rpc_seqno) { + sprintf(buf, " rpc_seqno=%d,", rpc_seqno); + strcat(updates, buf); + } + if (rpc_time != h.rpc_time) { + sprintf(buf, " rpc_time=%d,", rpc_time); + strcat(updates, buf); + } + if (timezone != h.timezone) { + sprintf(buf, " timezone=%d,", timezone); + strcat(updates, buf); + } + if (strcmp(domain_name, h.domain_name)) { + sprintf(buf, " domain_name='%s',", domain_name); + strcat(updates, buf); + } + if (strcmp(serialnum, h.serialnum)) { + sprintf(buf, " serialnum='%s',", serialnum); + strcat(updates, buf); + } + if (strcmp(last_ip_addr, h.last_ip_addr)) { + sprintf(buf, " last_ip_addr='%s',", last_ip_addr); + strcat(updates, buf); + } + if (nsame_ip_addr != h.nsame_ip_addr) { + sprintf(buf, " nsame_ip_addr=%d,", nsame_ip_addr); + strcat(updates, buf); + } + if (on_frac != h.on_frac) { + sprintf(buf, " on_frac=%f,", on_frac); + strcat(updates, buf); + } + if (connected_frac != h.connected_frac) { + sprintf(buf, " connected_frac=%f,", connected_frac); + strcat(updates, buf); + } + if (active_frac != h.active_frac) { + sprintf(buf, " active_frac=%f,", active_frac); + strcat(updates, buf); + } + if (p_ncpus != h.p_ncpus) { + sprintf(buf, " p_ncpus=%d,", p_ncpus); + strcat(updates, buf); + } + if (strcmp(p_vendor, h.p_vendor)) { + sprintf(buf, " p_vendor='%s',", p_vendor); + strcat(updates, buf); + } + if (strcmp(p_model, h.p_model)) { + sprintf(buf, " p_model='%s',", p_model); + strcat(updates, buf); + } + if (p_fpops != h.p_fpops) { + sprintf(buf, " p_fpops=%f,", p_fpops); + strcat(updates, buf); + } + if (p_iops != h.p_iops) { + sprintf(buf, " p_iops=%f,", p_iops); + strcat(updates, buf); + } + if (p_membw != h.p_membw) { + sprintf(buf, " p_membw=%f,", p_membw); + strcat(updates, buf); + } + if (strcmp(os_name, h.os_name)) { + sprintf(buf, " os_name='%s',", os_name); + strcat(updates, buf); + } + if (strcmp(os_version, h.os_version)) { + sprintf(buf, " os_version='%s',", os_version); + strcat(updates, buf); + } + if (m_nbytes != h.m_nbytes) { + sprintf(buf, " m_nbytes=%f,", m_nbytes); + strcat(updates, buf); + } + if (m_cache != h.m_cache) { + sprintf(buf, " m_cache=%f,", m_cache); + strcat(updates, buf); + } + if (m_swap != h.m_swap) { + sprintf(buf, " m_swap=%f,", m_swap); + strcat(updates, buf); + } + if (d_total != h.d_total) { + sprintf(buf, " d_total=%f,", d_total); + strcat(updates, buf); + } + if (d_free != h.d_free) { + sprintf(buf, " d_free=%f,", d_free); + strcat(updates, buf); + } + if (d_boinc_used_total != h.d_boinc_used_total) { + sprintf(buf, " d_boinc_used_total=%f,", d_boinc_used_total); + strcat(updates, buf); + } + if (d_boinc_used_project != h.d_boinc_used_project) { + sprintf(buf, " d_boinc_used_project=%f,", d_boinc_used_project); + strcat(updates, buf); + } + if (d_boinc_max != h.d_boinc_max) { + sprintf(buf, " d_boinc_max=%f,", d_boinc_max); + strcat(updates, buf); + } + if (n_bwup != h.n_bwup) { + sprintf(buf, " n_bwup=%f,", n_bwup); + strcat(updates, buf); + } + if (credit_per_cpu_sec != h.credit_per_cpu_sec) { + sprintf(buf, " credit_per_cpu_sec=%f,", credit_per_cpu_sec); + strcat(updates, buf); + } + if (strcmp(venue, h.venue)) { + sprintf(buf, " venue='%s',", venue); + strcat(updates, buf); + } + if (nresults_today != h.nresults_today) { + sprintf(buf, " nresults_today=%d,", nresults_today); + strcat(updates, buf); + } + if (avg_turnaround != h.avg_turnaround) { + sprintf(buf, " avg_turnaround=%f,", avg_turnaround); + strcat(updates, buf); + } + if (strcmp(host_cpid, h.host_cpid)) { + sprintf(buf, " host_cpid='%s',", host_cpid); + strcat(updates, buf); + } + if (strcmp(external_ip_addr, h.external_ip_addr)) { + sprintf(buf, " external_ip_addr='%s',", external_ip_addr); + strcat(updates, buf); + } + if (max_results_day != h.max_results_day) { + sprintf(buf, " max_results_day=%d,", max_results_day); + strcat(updates, buf); + } + + int n = strlen(updates); + if (n == 0) { + return 0; + } + + // trim the final comma + // + updates[n-1] = 0; + + sprintf(query, "update host set %s where id=%d", updates, id); + return db->do_query(query); +} + void DB_WORKUNIT::db_print(char* buf){ sprintf(buf, "create_time=%d, appid=%d, " diff --git a/db/boinc_db.h b/db/boinc_db.h index 820e8bc727..2c179b3b82 100755 --- a/db/boinc_db.h +++ b/db/boinc_db.h @@ -215,7 +215,6 @@ struct HOST { double p_iops; // measured integer ops/sec of CPU double p_membw; // measured memory bandwidth (bytes/sec) of CPU // The above are per CPU, not total - double p_calculated; // when the above were calculated char os_name[256]; // Name of operating system char os_version[256]; // Version of operating system @@ -525,6 +524,7 @@ class DB_HOST : public DB_BASE, public HOST { public: DB_HOST(DB_CONN* p=0); int get_id(); + int update_diff(HOST&); void db_print(char*); void db_parse(MYSQL_ROW &row); void operator=(HOST& r) {HOST::operator=(r);} diff --git a/doc/credit.php b/doc/credit.php index d755331e43..2eda2df7ce 100644 --- a/doc/credit.php +++ b/doc/credit.php @@ -70,29 +70,35 @@ Each time new credit is granted, the following function is used to update the recent average credit of the host, user and team:
",htmlspecialchars("
-#define CREDIT_HALF_LIFE  (SECONDS_IN_DAY*7)
 
-// Update an estimate of \"units per day\" of something (credit or CPU time).
-// The estimate is exponentially averaged with a given half-life
-// (i.e. if no new work is done, the average will decline by 50% in this time).
-// This function can be called either with new work,
-// or with zero work to decay an existing average.
-//
 void update_average(
-    double now,                     // current time
     double work_start_time,       // when new work was started
                                     // (or zero if no new work)
     double work,                    // amount of new work
+    double half_life,
     double& avg,                    // average work per day (in and out)
     double& avg_time                // when average was last computed
 ) {
+    double now = dtime();
+
     if (avg_time) {
-        double diff = now - avg_time;
-        double diff_days = diff/SECONDS_PER_DAY;
-        double weight = exp(-diff*M_LN2/CREDIT_HALF_LIFE);
+        double diff, diff_days, weight;
+
+        diff = now - avg_time;
+        if (diff<0) diff=0;
+
+        diff_days = diff/SECONDS_PER_DAY;
+        weight = exp(-diff*M_LN2/half_life);
+
         avg *= weight;
-        avg += (1-weight)*(work/diff_days);
-    } else {
+
+        if ((1.0-weight) > 1.e-6) {
+	    avg += (1-weight)*(work/diff_days);
+        }
+        else {
+            avg += M_LN2*work*SECONDS_PER_DAY/half_life;
+	}
+    } else if (work) {
         double dd = (now - work_start_time)/SECONDS_PER_DAY;
         avg = work/dd;
     }
diff --git a/sched/handle_request.C b/sched/handle_request.C
index 515ab66e1d..090a1e166a 100644
--- a/sched/handle_request.C
+++ b/sched/handle_request.C
@@ -302,7 +302,6 @@ static int modify_host_struct(SCHEDULER_REQUEST& sreq, HOST& host) {
     host.p_fpops = sreq.host.p_fpops;
     host.p_iops = sreq.host.p_iops;
     host.p_membw = sreq.host.p_membw;
-    host.p_calculated = sreq.host.p_calculated;
     strncpy(host.os_name, sreq.host.os_name, sizeof(host.os_name));
     strncpy(host.os_version, sreq.host.os_version, sizeof(host.os_version));
     host.m_nbytes = sreq.host.m_nbytes;
@@ -312,13 +311,16 @@ static int modify_host_struct(SCHEDULER_REQUEST& sreq, HOST& host) {
     host.d_free = sreq.host.d_free;
     host.n_bwup = sreq.host.n_bwup;
     host.n_bwdown = sreq.host.n_bwdown;
+    if (strlen(sreq.host.host_cpid)) {
+        strcpy(host.host_cpid, sreq.host.host_cpid);
+    }
     host.fix_nans();
 
     compute_credit_rating(host);
     return 0;
 }
 
-static int update_host_record(HOST& xhost, USER& user) {
+static int update_host_record(HOST& initial_host, HOST& xhost, USER& user) {
     DB_HOST host;
     int retval;
     char buf[1024];
@@ -333,7 +335,7 @@ static int update_host_record(HOST& xhost, USER& user) {
     if (p) {
         strlcpy(host.external_ip_addr, p, sizeof(host.external_ip_addr));
     }
-    retval = host.update();
+    retval = host.update_diff(initial_host);
     if (retval) {
         log_messages.printf(SCHED_MSG_LOG::CRITICAL, "host.update() failed: %d\n", retval);
     }
@@ -881,6 +883,7 @@ void process_request(
     bool ok_to_send_work = true;
     bool have_no_work;
     char buf[256];
+    HOST initial_host;
 
     // if different major version of BOINC, just send a message
     //
@@ -942,6 +945,7 @@ void process_request(
     if (reply.user.id == 0) {
         log_messages.printf(SCHED_MSG_LOG::CRITICAL, "No user ID!\n");
     }
+    initial_host = reply.host;
 
     log_messages.printf(
         SCHED_MSG_LOG::NORMAL,
@@ -1031,7 +1035,7 @@ void process_request(
         handle_msgs_to_host(reply);
     }
 
-    update_host_record(reply.host, reply.user);
+    update_host_record(initial_host, reply.host, reply.user);
 
 leave:
     if (!have_no_work) {
diff --git a/sched/server_types.C b/sched/server_types.C
index 55262952a6..4b59007885 100644
--- a/sched/server_types.C
+++ b/sched/server_types.C
@@ -639,7 +639,6 @@ int RESULT::parse_from_client(FILE* fin) {
 //
 int HOST::parse(FILE* fin) {
     char buf[256];
-    int p_fpop_err, p_iop_err, p_membw_err;
 
     p_ncpus = 1;
     while (fgets(buf, 256, fin)) {
@@ -655,10 +654,6 @@ int HOST::parse(FILE* fin) {
         else if (parse_double(buf, "", p_fpops)) continue;
         else if (parse_double(buf, "", p_iops)) continue;
         else if (parse_double(buf, "", p_membw)) continue;
-        else if (parse_int(buf, "", p_fpop_err)) continue;
-        else if (parse_int(buf, "", p_iop_err)) continue;
-        else if (parse_int(buf, "", p_membw_err)) continue;
-        else if (parse_double(buf, "", p_calculated)) continue;
         else if (parse_str(buf, "", os_name, sizeof(os_name))) continue;
         else if (parse_str(buf, "", os_version, sizeof(os_version))) continue;
         else if (parse_double(buf, "", m_nbytes)) continue;
@@ -669,7 +664,9 @@ int HOST::parse(FILE* fin) {
         else if (parse_double(buf, "", n_bwup)) continue;
         else if (parse_double(buf, "", n_bwdown)) continue;
         else {
-            log_messages.printf(SCHED_MSG_LOG::NORMAL, "HOST::parse(): unrecognized: %s\n", buf);
+            log_messages.printf(SCHED_MSG_LOG::NORMAL,
+                "HOST::parse(): unrecognized: %s\n", buf
+            );
         }
     }
     return ERR_XML_PARSE;