public inbox for b.a.t.m.a.n@lists.open-mesh.org
 help / color / mirror / Atom feed
From: Nathan Wharton <naw@greptar.com>
To: The list for a Better Approach To Mobile Ad-hoc Networking
	<B.A.T.M.A.N@open-mesh.net>
Subject: [B.A.T.M.A.N.] times wrapper
Date: Thu, 30 Apr 2009 10:43:02 -0500	[thread overview]
Message-ID: <4313f3060904300843ra2f7a71o37f39780a797cfd2@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 904 bytes --]

When I first started meshing, I used olsrd.  There was a problem on
our platform that caused olsrd packets to stop going out after the
board had been up about 5 minutes.  The outage lasted about 40
seconds, then came back.  It turns out that there is a problem with
the times() call that will return -1 for the 4096 jiffies before wrap
around.  This caused no apparent change in time during that duration,
so no packets were sent.  Also, for some reason on our platform,
times() starts out about 5 minutes before wrap around.

I found a work around elsewhere (and I leave credit in the patch) for
some other software that was failing every 400 something days.  I
applied this to olsrd, and the problem went away.

When I switched to batman, I saw that times() is used in it as well,
so I made the patch attached.  So, if anyone sees packets fail to come
from batman for 40 seconds, they might need this.

[-- Attachment #2: 001-times.patch --]
[-- Type: application/octet-stream, Size: 2359 bytes --]

diff -ruN batmand-r1178.orig/posix/posix.c batmand-r1178/posix/posix.c
--- batmand-r1178.orig/posix/posix.c	2008-12-29 09:35:38.000000000 -0600
+++ batmand-r1178/posix/posix.c	2009-01-02 13:31:27.000000000 -0600
@@ -49,11 +49,49 @@
 
 static pthread_mutex_t batman_clock_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static struct tms dummy_tms_struct;
+static clock_t
+times_wrapper(void) /* Make times(2) behave rationally on Linux */
+{
+       int             save_errno = errno;
+       clock_t ret;
+
+       /*
+        * times(2) really returns an unsigned value ...
+        *
+        * We don't check to see if we got back the error value (-1), because
+        * the only possibility for an error would be if the address of
+        * dummy_tms_struct was invalid.  Since it's a
+        * compiler-generated address, we assume that errors are impossible.
+        * And, unfortunately, it is quite possible for the correct return
+        * from times(2) to be exactly (clock_t)-1.  Sigh...
+        *
+        */
+       errno   = 0;
+       ret     = times(&dummy_tms_struct);
+
+/*
+ *     This is to work around a bug in the system call interface
+ *     for times(2) found in glibc on Linux (and maybe elsewhere)
+ *     It changes the return values from -1 to -4096 all into
+ *     -1 and then dumps the -(return value) into errno.
+ *
+ *     This totally bizarre behavior seems to be widespread in
+ *     versions of Linux and glibc.
+ *
+ *     Many thanks to Wolfgang Dumhs <wolfgang.dumhs (at) gmx.at>
+ *     for finding and documenting this bizarre behavior.
+ */
+       if (errno != 0) {
+               ret = (clock_t) (-errno);
+       }
+       errno = save_errno;
+       return ret;
+}
 
 static void update_internal_clock(void)
 {
-	struct tms tp;
-	clock_t current_clock_tick = times(&tp);
+	clock_t current_clock_tick = times_wrapper();
 
 	batman_clock_ticks += (current_clock_tick - last_clock_tick);
 	last_clock_tick = current_clock_tick;
@@ -553,7 +591,6 @@
 int main( int argc, char *argv[] ) {
 
 	int8_t res;
-	struct tms tp;
 
 	/* check if user is root */
 	if ( ( getuid() ) || ( getgid() ) ) {
@@ -575,7 +612,7 @@
 
 	/* save start value */
 	system_tick = (float)sysconf(_SC_CLK_TCK);
-	last_clock_tick = times(&tp);
+	last_clock_tick = times_wrapper();
 	update_internal_clock();
 
 	apply_init_args( argc, argv );

             reply	other threads:[~2009-04-30 15:43 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-30 15:43 Nathan Wharton [this message]
2009-04-30 16:27 ` [B.A.T.M.A.N.] times wrapper L. Aaron Kaplan
2009-05-01  7:55 ` Marek Lindner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4313f3060904300843ra2f7a71o37f39780a797cfd2@mail.gmail.com \
    --to=naw@greptar.com \
    --cc=B.A.T.M.A.N@open-mesh.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox