genrand_unix problem on Solaris
- From: Laszlo PETER <Laszlo Peter ireland sun com>
- To: orbit-list gnome org
- Subject: genrand_unix problem on Solaris
- Date: Mon, 19 Feb 2001 19:45:26 +0000
Hi,
I'm not subscribed to this list, so please, CC: me on any replies. Thx.
I've found a serious problem with genrand_unix on Solaris.
It took ages for nautilus to start or to change to a different directory.
I found that it spends most of the time in genrand_unix (ORBit/src/orb/genrand.c),
so I had a closer look.
According to the Solaris man page of setitimer:
In the current and previous releases, when
setitimer(ITIMER_REAL, ...) is called in a mul-
tithreaded process linked with -lthread (Solaris
threads) or -lpthread (POSIX threads; see stan-
dards(5)), the resulting SIGALRM is sent to the bound
thread that called setitimer(); setitimer() has a
per-thread semantic when called from a bound thread.
Also, calling this routine from an unbound thread is
not guaranteed to work as in the case of bound
threads. The resulting SIGALRM may be sent to some
other thread (see alarm(2)). This is a bug and will
not be fixed since the per-thread semantic is going to
be discontinued.
Hence, for multithreaded (Solaris or POSIX) programs
in the current and previous releases, the only reli-
able way to use the ITIMER_REAL flag is to call it
from a bound thread which does not mask SIGALRM and to
expect the SIGALRM to be delivered to this bound
thread.
New MT applications should not use this flag, and
should use alarm(2) instead.
Since nautilus is an MT app, and it uses unbound threads
(in gnome-vfs/libgnomevfs-pthreads),
it looks like it didn't always get the ALARM signal and kept waiting
for a long-long time...
Of course you can't implement genrand_unix using alarm(), so
I wrote a new genrand function that uses lrand48() to generate
random numbers. Attached is my patch.
Using this patch nautilus started to work much-much faster.
Let me know if you have any other solutions to this problem.
Cheers,
Laca
Index: ORBit/configure.in
===================================================================
RCS file: /export/CVS/GNOME-RE/ORBit/configure.in,v
retrieving revision 1.98.4.10
diff -u -r1.98.4.10 configure.in
--- ORBit/configure.in 2001/01/18 20:16:42 1.98.4.10
+++ ORBit/configure.in 2001/02/16 11:40:03
@@ -133,7 +133,7 @@
fi
AC_SUBST(ORBIT_HAVE_ALLOCA_H)
-AC_CHECK_FUNCS(poll basename)
+AC_CHECK_FUNCS(poll basename lrand48)
AC_CHECK_FUNC(socket,,[AC_CHECK_LIB(socket,socket)])
AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)])
Index: ORBit/src/orb/genrand.c
===================================================================
RCS file: /export/CVS/GNOME-RE/ORBit/src/orb/genrand.c,v
retrieving revision 1.2.4.1
diff -u -r1.2.4.1 genrand.c
--- ORBit/src/orb/genrand.c 2001/01/18 20:16:44 1.2.4.1
+++ ORBit/src/orb/genrand.c 2001/02/16 11:40:03
@@ -1,3 +1,4 @@
+#include <config.h>
#include "genrand.h"
#include "ORBitutil/util.h"
#include <unistd.h>
@@ -50,6 +51,24 @@
}
static gboolean
+genrand_lrand48(guchar *buffer, int buf_len)
+{
+#ifdef HAVE_LRAND48
+#ifndef LRAND48_MAX
+#define LRAND48_MAX 2147483648.0
+#endif
+ int i;
+ srand48(random());
+
+ for(i = 0; i < buf_len; i++)
+ buffer[i] = (guchar) (lrand48() / (LRAND48_MAX / 256));
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+static gboolean
genrand_unix(guchar *buffer, int buf_len)
{
struct sigaction sa, oldsa;
@@ -105,6 +124,8 @@
g_return_if_fail(buf_len);
if(genrand_dev(buffer, buf_len))
+ return;
+ else if(genrand_lrand48(buffer, buf_len))
return;
else if(genrand_unix(buffer, buf_len))
return;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]