From 54957d4f584c4720d67cb21fc8860ce114fe37c5 Mon Sep 17 00:00:00 2001
From: David Anderson
Date: Sun, 7 Sep 2003 03:11:03 +0000
Subject: [PATCH] *** empty log message ***
svn path=/trunk/boinc/; revision=2287
---
checkin_notes | 9 +++++++++
client/net_xfer.C | 26 ++++++++++++++++----------
client/net_xfer.h | 2 +-
doc/api.php | 20 +++++++++++++-------
lib/util.C | 3 ++-
5 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/checkin_notes b/checkin_notes
index 448c9b79de..c1299baec4 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -6206,3 +6206,12 @@ Karl 2003/09/05
Sched/
handle_request.C
+
+David Sept 6 2003
+ - fixed bug where do_select wasn't sleeping
+ when there are no fds (doh!!)
+
+ client/
+ net_xfer.C,h
+ lib/
+ util.C
diff --git a/client/net_xfer.C b/client/net_xfer.C
index 00e95151c5..3351d249a0 100644
--- a/client/net_xfer.C
+++ b/client/net_xfer.C
@@ -296,13 +296,11 @@ int NET_XFER_SET::remove(NET_XFER* nxp) {
bool NET_XFER_SET::poll() {
double bytes_xferred;
int retval;
- struct timeval timeout;
time_t t = time(0);
bool action = false;
while (1) {
- timeout.tv_sec = timeout.tv_usec = 0;
- retval = do_select(bytes_xferred, timeout);
+ retval = do_select(bytes_xferred, 0);
if (retval) break;
if (bytes_xferred == 0) break;
action = true;
@@ -311,6 +309,11 @@ bool NET_XFER_SET::poll() {
return action;
}
+static void double_to_timeval(double x, timeval& t) {
+ t.tv_sec = (int)x;
+ t.tv_usec = (int)(1000000*(x - (int)x));
+}
+
// Wait at most x seconds for network I/O to become possible,
// then do up to about .5 seconds of I/O.
// This is used only by the cmdline client, to sleep without slowing down I/O.
@@ -318,11 +321,8 @@ bool NET_XFER_SET::poll() {
int NET_XFER_SET::net_sleep(double x) {
int retval;
double bytes_xferred;
- struct timeval timeout;
- timeout.tv_sec = (int)x;
- timeout.tv_usec = (int)(1000000*(x - (int)x));
- retval = do_select(bytes_xferred, timeout);
+ retval = do_select(bytes_xferred, x);
if (retval) return retval;
if (bytes_xferred) {
return poll();
@@ -334,10 +334,11 @@ int NET_XFER_SET::net_sleep(double x) {
// then do I/O on as many sockets as possible, subject to rate limits
// Transfer at most one block per socket.
//
-int NET_XFER_SET::do_select(double& bytes_transferred, timeval& timeout) {
+int NET_XFER_SET::do_select(double& bytes_transferred, double timeout) {
int n, fd, retval, nsocks_queried;
socklen_t i;
NET_XFER *nxp;
+ struct timeval tv;
ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_NET_XFER);
@@ -387,8 +388,13 @@ int NET_XFER_SET::do_select(double& bytes_transferred, timeval& timeout) {
}
FD_SET(nxp->socket, &error_fds);
}
- if (nsocks_queried==0) return 0;
- n = select(FD_SETSIZE, &read_fds, &write_fds, &error_fds, &timeout);
+ if (nsocks_queried==0) {
+ boinc_sleep(timeout);
+ return 0;
+ }
+
+ double_to_timeval(timeout, tv);
+ n = select(FD_SETSIZE, &read_fds, &write_fds, &error_fds, &tv);
scope_messages.printf(
"NET_XFER_SET::do_select(): queried %d, returned %d\n",
nsocks_queried, n
diff --git a/client/net_xfer.h b/client/net_xfer.h
index bea57314bb..bb80ecfe80 100644
--- a/client/net_xfer.h
+++ b/client/net_xfer.h
@@ -89,7 +89,7 @@ public:
int remove(NET_XFER*);
bool poll();
int net_sleep(double);
- int do_select(double& bytes_transferred, struct timeval& timeout);
+ int do_select(double& bytes_transferred, double timeout);
NET_XFER* lookup_fd(int); // lookup by fd
void check_active(bool&, bool&);
};
diff --git a/doc/api.php b/doc/api.php
index 642645b950..f12a8fb9a1 100644
--- a/doc/api.php
+++ b/doc/api.php
@@ -35,7 +35,6 @@ For example, instead of
the application might use
-
char resolved_name[256];
retval = boinc_resolve_filename(\"my_file\", resolved_name);
@@ -70,8 +69,16 @@ then call
void boinc_checkpoint_completed();
-A call to boinc_time_to_checkpoint() is extremely fast,
-so there is little penalty in calling it frequently.
+boinc_time_to_checkpoint() is fast
+(it usually makes no system calls),
+so can be called frequently (hundreds or thousands of times a second).
+
+
+boinc_time_to_checkpoint() performs other time-based functions;
+e.g. it periodically measures the application's CPU time and
+reports it to the core client.
+So, even for applications that don't do checkpointing,
+it should be called at least once a second.
Atomic file update
@@ -111,14 +118,13 @@ This is done using
Communicating with the core client
The core client GUI displays the percent done of workunits in progress.
-To keep this display current, an application should
-periodically call
+To keep this display current, an application should periodically call
boinc_fraction_done(double fraction_done);
The fraction_done argument is a rough estimate of the
workunit fraction complete (0 to 1).
-This function is extremely fast and can be called often.
+This function is fast and can be called frequently.
The following functions get information from the core client;
@@ -150,7 +156,7 @@ list_item("team_expavg_credit", " team's recent average work per day.");
list_end();
echo "
-It may call
+An application may call
int boinc_cpu_time(double &cpu_time, double& working_set_size);
diff --git a/lib/util.C b/lib/util.C
index 9889e6c437..fcfd576697 100755
--- a/lib/util.C
+++ b/lib/util.C
@@ -175,7 +175,8 @@ void boinc_sleep(double seconds) {
::Sleep((int)(1000*seconds));
#else
sleep((int)seconds);
- usleep((int)fmod(seconds*1000000,1000000));
+ int x = (int)fmod(seconds*1000000,1000000);
+ if (x) usleep(x);
#endif
}