id>$nresults";
}
function sched_log_name($x) {
if ($x == 0) return "NO_SUCH_LOG";
return gmdate('Y-m-d_H/Y-m-d_H:i', $x) . ".txt";
}
function sched_log_link($x) {
return "" . time_str($x) . "";
}
function location_form($host) {
$none = "selected";
$h=$w=$s="";
if ($host->venue == "home") $h = "selected";
if ($host->venue == "work") $w = "selected";
if ($host->venue == "school") $s = "selected";
$x = "
";
return $x;
}
function show_host($host, $private, $ipprivate, $user) {
start_table();
row1("Computer information");
if ($private) {
if ($ipprivate) {
row2("IP address", "$host->last_ip_addr
(same the last $host->nsame_ip_addr times)");
if (strcmp($host->last_ip_addr, $host->external_ip_addr)) row2("External IP address", $host->external_ip_addr);
} else {
row2("IP address", "id&ipprivate=1>Show IP address");
}
row2("Domain name", $host->domain_name);
$x = $host->timezone/3600;
if ($x >= 0) $x="+$x";
row2("Local Standard Time", "UTC $x hours");
}
if ($private) {
row2("Name", $host->domain_name);
}
if (!$private) {
$user = lookup_user_id($host->userid);
if ($user && $user->show_hosts) {
row2("Owner", user_links($user));
} else {
row2("Owner", "Anonymous");
}
}
row2("Created", time_str($host->create_time));
row2("Total Credit", format_credit_large($host->total_credit));
row2("Recent average credit", format_credit($host->expavg_credit));
row2("CPU type", "$host->p_vendor
$host->p_model");
row2("Number of CPUs", $host->p_ncpus);
row2("Operating System", "$host->os_name
$host->os_version");
$x = $host->m_nbytes/(1024*1024);
$y = round($x, 2);
row2("Memory", "$y MB");
$x = $host->m_cache/1024;
$y = round($x, 2);
row2("Cache", "$y KB");
if ($private) {
$x = $host->m_swap/(1024*1024);
$y = round($x, 2);
row2("Swap space", "$y MB");
$x = $host->d_total/(1024*1024*1024);
$y = round($x, 2);
row2("Total disk space", "$y GB");
$x = $host->d_free/(1024*1024*1024);
$y = round($x, 2);
row2("Free Disk Space", "$y GB");
}
$x = $host->p_fpops/(1000*1000);
$y = round($x, 2);
row2("Measured floating point speed", "$y million ops/sec");
$x = $host->p_iops/(1000*1000);
$y = round($x, 2);
row2("Measured integer speed", "$y million ops/sec");
$x = $host->n_bwup/(1024);
$y = round($x, 2);
if ($y > 0) {
row2("Average upload rate", "$y KB/sec");
} else {
row2("Average upload rate", "Unknown");
}
$x = $host->n_bwdown/(1024);
$y = round($x, 2);
if ($y > 0) {
row2("Average download rate", "$y KB/sec");
} else {
row2("Average download rate", "Unknown");
}
$x = $host->avg_turnaround/86400;
row2("Average turnaround time", round($x, 2)." days");
$mrd= $host->max_results_day;
row2("Maximum daily WU quota per CPU", $mrd."/day");
$config = get_config();
if (parse_bool($config, "show_results")) {
$nresults = host_nresults($host);
if ($nresults) {
$results = "id>$nresults";
} else {
$results = "0";
}
row2("Tasks", $results);
}
if ($private) {
row2("Number of times client has contacted server", $host->rpc_seqno);
row2("Last time contacted server", sched_log_link($host->rpc_time));
row2("% of time BOINC client is running", 100*$host->on_frac." %");
if ($host->connected_frac > 0) {
row2("While BOINC running, % of time host has an Internet connection", 100*$host->connected_frac." %");
}
row2("While BOINC running, % of time work is allowed", 100*$host->active_frac." %");
if ($host->cpu_efficiency) {
row2("Average CPU efficiency", $host->cpu_efficiency);
}
if ($host->duration_correction_factor) {
row2("Result duration correction factor", $host->duration_correction_factor);
}
row2("Location", location_form($host));
if ($nresults == 0) {
$x = " | id".url_tokens($user->authenticator).">Delete this computer ";
} else {
$x = "";
}
row2("Click to", "id>Merge this computer $x");
//row2("Click to", "id>recompute credit");
}
echo "\n";
}
// the following is used for list of top hosts
//
function top_host_table_start($sort_by) {
start_table();
echo "";
echo "Computer ID Click for more info | \n";
echo "Rank | ";
echo "Owner | \n";
if ($sort_by == 'total_credit') {
echo "
Recent average credit |
Total credit |
";
} else {
echo "
Recent average credit |
Total credit |
";
}
echo "
CPU type |
Operating system |
";
}
function host_nresults($host) {
return BoincResult::count("hostid=$host->id");
}
// If private is true, we're showing the host to its owner,
// so it's OK to show the domain name etc.
// If private is false, show the owner's name only if they've given permission
//
function show_host_row($host, $i, $private, $show_owner) {
$user = BoincUser::lookup_id($host->userid);
echo "", host_link($host->id), " | \n";
if ($private) {
echo " $host->domain_name";
} else {
echo " | $i | \n
";
if ($show_owner) {
if ($user && $user->show_hosts) {
echo "", user_links($user), " | \n";
} else {
echo "Anonymous | \n";
}
}
}
if ($show_owner) {
// This is used in the "top computers" display
//
printf("
%s |
%s |
%s %s |
%s %s | ",
format_credit($host->expavg_credit), format_credit_large($host->total_credit),
$host->p_vendor, $host->p_model,
$host->os_name, $host->os_version
);
} else {
// This is used in constructing list of computers for a given user
//
$config = get_config();
if (parse_bool($config, "show_results")) {
$ltr="".link_to_results($host)." | ";
} else {
$ltr="";
}
printf("
%s |
%s |
%s %s |
%s %s |
%s
%s | ",
format_credit($host->expavg_credit), format_credit_large($host->total_credit),
$host->p_vendor, $host->p_model,
$host->os_name, $host->os_version, $ltr, sched_log_link($host->rpc_time)
);
}
echo "
\n";
}
// return true iff it's possible that the hosts are actually
// the same machine
//
function ghz($x) {
$y = explode(" ", $x);
foreach ($y as $z) {
if (strstr($z, "GHz")) return $z;
if (strstr($z, "MHz")) return $z;
}
}
function cpus_compatible($host1, $host2) {
// we screwed around with Intel processor names,
// so count them as compatible if both contain "Intel" and "Pentium",
// and don't have conflicting clock rate info
// Get rid of cpu capabilities before check
$pos = strpos($host1->p_model, '[');
$host1pm = $host1->p_model;
if($pos) {
$host1pm = trim(substr($host1->p_model, 0, $pos));
}
$pos = strpos($host2->p_model, '[');
$host2pm = $host2->p_model;
if($pos) {
$host2pm = trim(substr($host2->p_model, 0, $pos));
}
$p1 = "$host1->p_vendor $host1pm";
$p1 = "$host2->p_vendor $host2pm";
if (strstr($p1, "Pentium") && strstr($p1, "Intel")
&& strstr($p2, "Pentium") && strstr($p2, "Intel")
) {
$g1 = ghz($p1);
$g2 = ghz($p2);
if ($g1 && $g2) {
if ($g1 != $g2) return false;
} else {
return false;
}
} else if (strstr($p1, "AuthenticAMD") && strstr($p2, "AuthenticAMD")) {
return true;
} else {
if ($host2->p_vendor != $host1->p_vendor) return false;
// they're compatible if models are the same,
// or contents of [family/model/stepping] are the same
if ($host1pm != $host2pm) return false;
}
return true;
}
// does one host strictly precede the other?
//
function times_disjoint($host1, $host2) {
if ($host1->rpc_time < $host2->create_time) return true;
if ($host2->rpc_time < $host1->create_time) return true;
return false;
}
function os_compatible($host1, $host2) {
if (strstr($host1->os_name, "Windows") && strstr($host2->os_name, "Windows")) return true;
if (strstr($host1->os_name, "Linux") && strstr($host2->os_name, "Linux")) return true;
if (strstr($host1->os_name, "Darwin") && strstr($host2->os_name, "Darwin")) return true;
if (strstr($host1->os_name, "SunOS") && strstr($host2->os_name, "SunOS")) return true;
if ($host1->os_name == $host2->os_name) return true;
return false;
}
// Return true if it's possible that the two host records
// correspond to the same host
// NOTE: the cheat-proofing comes from checking
// that their time intervals are disjoint.
// So the CPU/OS checks don't have to be very strict.
//
function hosts_compatible($host1, $host2) {
// skip disjoint-time check if one host or other has no credit
//
if ($host1->total_credit && $host2->total_credit) {
if (!times_disjoint($host1, $host2)) {
echo "
h2 $host2->create_time $host2->rpc_time";
return false;
}
}
if (!os_compatible($host1, $host2)) {
//echo "
$host1->id $host2->id: OS not compatible: ($host1->os_name, $host2->os_name)\n";
return false;
}
if (!cpus_compatible($host1, $host2)) {
//echo "
$host1->id $host2->id: CPU not compatible ($host1->p_vendor $host1->p_model, $host2->p_vendor $host2->p_model)\n";
return false;
}
return true;
}
// recompute host's average credit by scanning results.
// Could be expensive if lots of results!
//
function host_update_credit($hostid) {
$total = 0;
$avg = 0;
$avg_time = 0;
$results = BoincResult::enum("hostid=$hostid order by received_time");
foreach($results as $result) {
if ($result->granted_credit <= 0) continue;
$total += $result->granted_credit;
update_average(
$result->received_time,
$result->sent_time,
$result->granted_credit,
$avg,
$avg_time
);
//echo "
$avg\n";
}
// do a final decay
//
$now = time();
update_average(now, 0, 0, $avg, $avg_time);
$host = new BoincHost();
$host->id = hostid;
$host->update("total_credit=$total, expavg_credit=$avg, expavg_time=$now");
}
// decay a host's average credit
//
function host_decay_credit($host) {
$avg = $host->expavg_credit;
$avg_time = $host->expavg_time;
$now = time(0);
update_average($now, 0, 0, $avg, $avg_time);
$host->update("expavg_credit=$avg, expavg_time=$now");
}
// if the host hasn't received new credit for ndays,
// decay its average and return true
//
function host_inactive_ndays($host, $ndays) {
$diff = time() - $host->expavg_time;
if ($diff > $ndays*86400) {
host_decay_credit($host);
return true;
}
return false;
}
// invariant: old_host.create_time < new_host.create_time
//
function merge_hosts($old_host, $new_host) {
if ($old_host->id == $new_host->id) {
return "same host";
}
if (!hosts_compatible($old_host, $new_host)) {
return "Can't merge host $old_host->id into $new_host->id - they're incompatible";
}
echo "
Merging host $old_host->id into host $new_host->id\n";
// decay the average credit of both hosts
//
$now = time();
update_average($now, 0, 0, $old_host->expavg_credit, $old_host->expavg_time);
update_average($now, 0, 0, $new_host->expavg_credit, $new_host->expavg_time);
// update the database:
// - add credit from old to new host
// - change results to refer to new host
// - put old host in "zombie" state
// - update rpc_seqno if needed
//
$total_credit = $old_host->total_credit + $new_host->total_credit;
$recent_credit = $old_host->expavg_credit + $new_host->expavg_credit;
$result = $new_host->update("total_credit=$total_credit, expavg_credit=$recent_credit, expavg_time=$now");
if (!$result) {
return "Couldn't update credit of new computer";
}
$result = BoincResult::update_aux("hostid=$new_host->id where hostid=$old_host->id");
if (!$result) {
return "Couldn't update results";
}
$result = $old_host->update("total_credit=0, expavg_credit=0, userid=0, rpc_seqno=$new_host->id");
if (!$result) {
return "Couldn't retire old computer";
}
echo "
Retired old computer $old_host->id\n";
return 0;
}
?>