Re: [PATCH, TEST] Make functions in random.c thread safe

2012-10-10 Thread Alexey Suslikov
Hi.

Me and Roman are curious about zero comments on this.

We'll try to improve the diff if it is not ok. Just let us know.

Anyone? :)

On Wed, Oct 3, 2012 at 4:06 PM, Alexey Suslikov
alexey.susli...@gmail.com wrote:
 Hi.

 Is there any progress/comments on this?

 On Fri, Sep 28, 2012 at 11:29 PM, Alexey Suslikov
 alexey.susli...@gmail.com wrote:
 Hi.

 With input from tedu@, guenther@ and others, below are:
 1) test case;
 2) backtrace for test case;
 3) locking diff;
 4) dmesg (amd64 GENERIC.MP built from 2012-09-28 CVS).

 Diff introduces no changes to srandomdev(): correct me if I'm wrong,
 but no mutex can be used since sysctl can sleep.

 Rebuild and reinstall in src/lib/librthread and src/lib/libc after applying
 the diff.

 Expect test case (and Kannel port of course) not crashing after rebuild
 and reinstall.

 Cheers,
 Alexey

 1) test case.

 #include pthread.h
 #include stdio.h
 #include stdlib.h
 #include assert.h
 #include unistd.h

 #define NUM_THREADS1800

 void *TaskCode(void *argument)
 {
 struct timeval  tv;

 gettimeofday(tv, 0);
 srandom((getpid()  16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);

 return NULL;
 }

 int main(void)
 {
 pthread_t threads[NUM_THREADS];
 int thread_args[NUM_THREADS];
 int rc, i;

 /* create all threads */
 for (i=0; iNUM_THREADS; ++i) {
 thread_args[i] = i;
 rc = pthread_create(threads[i], NULL, TaskCode, (void *) 
 thread_args[i]);
 assert(0 == rc);
 }

 /* wait for all threads to complete */
 for (i=0; iNUM_THREADS; ++i) {
 rc = pthread_join(threads[i], NULL);
 assert(0 == rc);
 }

 printf(Test srandom success\n);
 exit(EXIT_SUCCESS);
 }

 2) backtrace for test case.

 Program received signal SIGSEGV, Segmentation fault.
 [Switching to thread 1030380]
 0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
 387 *fptr += *rptr;

 (gdb) bt
 #0  0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
 #1  0x19d34d619169 in srandom (x=Variable x is not available.
 ) at /usr/src/lib/libc/stdlib/random.c:216
 #2  0x19d14fe1 in TaskCode (argument=0x7f7ea004) at
 test_srandom.c:14
 #3  0x19d34999d11e in _rthread_start (v=Variable v is not available.
 ) at /usr/src/lib/librthread/rthread.c:122
 #4  0x19d34d5f0f9b in __tfork_thread () at
 /usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:75
 Cannot access memory at address 0x19d344efb000

 3) locking diff.

 Index: lib/libc/include/thread_private.h
 ===
 RCS file: /cvs/src/lib/libc/include/thread_private.h,v
 retrieving revision 1.25
 diff -u -p -r1.25 thread_private.h
 --- lib/libc/include/thread_private.h   16 Oct 2011 06:29:56 -  1.25
 +++ lib/libc/include/thread_private.h   27 Sep 2012 10:48:45 -
 @@ -172,4 +172,16 @@ void   _thread_arc4_unlock(void);
 _thread_arc4_unlock();\
 } while (0)

 +void   _thread_random_lock(void);
 +void   _thread_random_unlock(void);
 +
 +#define _RANDOM_LOCK() do {\
 +   if (__isthreaded)   \
 +   _thread_random_lock();  \
 +   } while (0)
 +#define _RANDOM_UNLOCK()   do {\
 +   if (__isthreaded)   \
 +   _thread_random_unlock();\
 +   } while (0)
 +
  #endif /* _THREAD_PRIVATE_H_ */
 Index: lib/libc/stdlib/random.c
 ===
 RCS file: /cvs/src/lib/libc/stdlib/random.c,v
 retrieving revision 1.17
 diff -u -p -r1.17 random.c
 --- lib/libc/stdlib/random.c1 Jun 2012 01:01:57 -   1.17
 +++ lib/libc/stdlib/random.c27 Sep 2012 10:48:45 -
 @@ -35,6 +35,10 @@
  #include stdio.h
  #include stdlib.h
  #include unistd.h
 +#include thread_private.h
 +
 +static void srandom_unlocked(unsigned int);
 +static long random_unlocked(void);

  /*
   * random.c:
 @@ -186,8 +190,8 @@ static int rand_sep = SEP_3;
   * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
   * for default usage relies on values produced by this routine.
   */
 -void
 -srandom(unsigned int x)
 +static void
 +srandom_unlocked(unsigned int x)
  {
 int i;
 int32_t test;
 @@ -213,10 +217,18 @@ srandom(unsigned int x)
 fptr = state[rand_sep];
 rptr = state[0];
 for (i = 0; i  10 * rand_deg; i++)
 -   (void)random();
 +   (void)random_unlocked();
 }
  }

 +void
 

Re: [PATCH, TEST] Make functions in random.c thread safe

2012-10-03 Thread Alexey Suslikov
Hi.

Is there any progress/comments on this?

On Fri, Sep 28, 2012 at 11:29 PM, Alexey Suslikov
alexey.susli...@gmail.com wrote:
 Hi.

 With input from tedu@, guenther@ and others, below are:
 1) test case;
 2) backtrace for test case;
 3) locking diff;
 4) dmesg (amd64 GENERIC.MP built from 2012-09-28 CVS).

 Diff introduces no changes to srandomdev(): correct me if I'm wrong,
 but no mutex can be used since sysctl can sleep.

 Rebuild and reinstall in src/lib/librthread and src/lib/libc after applying
 the diff.

 Expect test case (and Kannel port of course) not crashing after rebuild
 and reinstall.

 Cheers,
 Alexey

 1) test case.

 #include pthread.h
 #include stdio.h
 #include stdlib.h
 #include assert.h
 #include unistd.h

 #define NUM_THREADS1800

 void *TaskCode(void *argument)
 {
 struct timeval  tv;

 gettimeofday(tv, 0);
 srandom((getpid()  16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);

 return NULL;
 }

 int main(void)
 {
 pthread_t threads[NUM_THREADS];
 int thread_args[NUM_THREADS];
 int rc, i;

 /* create all threads */
 for (i=0; iNUM_THREADS; ++i) {
 thread_args[i] = i;
 rc = pthread_create(threads[i], NULL, TaskCode, (void *) 
 thread_args[i]);
 assert(0 == rc);
 }

 /* wait for all threads to complete */
 for (i=0; iNUM_THREADS; ++i) {
 rc = pthread_join(threads[i], NULL);
 assert(0 == rc);
 }

 printf(Test srandom success\n);
 exit(EXIT_SUCCESS);
 }

 2) backtrace for test case.

 Program received signal SIGSEGV, Segmentation fault.
 [Switching to thread 1030380]
 0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
 387 *fptr += *rptr;

 (gdb) bt
 #0  0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
 #1  0x19d34d619169 in srandom (x=Variable x is not available.
 ) at /usr/src/lib/libc/stdlib/random.c:216
 #2  0x19d14fe1 in TaskCode (argument=0x7f7ea004) at
 test_srandom.c:14
 #3  0x19d34999d11e in _rthread_start (v=Variable v is not available.
 ) at /usr/src/lib/librthread/rthread.c:122
 #4  0x19d34d5f0f9b in __tfork_thread () at
 /usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:75
 Cannot access memory at address 0x19d344efb000

 3) locking diff.

 Index: lib/libc/include/thread_private.h
 ===
 RCS file: /cvs/src/lib/libc/include/thread_private.h,v
 retrieving revision 1.25
 diff -u -p -r1.25 thread_private.h
 --- lib/libc/include/thread_private.h   16 Oct 2011 06:29:56 -  1.25
 +++ lib/libc/include/thread_private.h   27 Sep 2012 10:48:45 -
 @@ -172,4 +172,16 @@ void   _thread_arc4_unlock(void);
 _thread_arc4_unlock();\
 } while (0)

 +void   _thread_random_lock(void);
 +void   _thread_random_unlock(void);
 +
 +#define _RANDOM_LOCK() do {\
 +   if (__isthreaded)   \
 +   _thread_random_lock();  \
 +   } while (0)
 +#define _RANDOM_UNLOCK()   do {\
 +   if (__isthreaded)   \
 +   _thread_random_unlock();\
 +   } while (0)
 +
  #endif /* _THREAD_PRIVATE_H_ */
 Index: lib/libc/stdlib/random.c
 ===
 RCS file: /cvs/src/lib/libc/stdlib/random.c,v
 retrieving revision 1.17
 diff -u -p -r1.17 random.c
 --- lib/libc/stdlib/random.c1 Jun 2012 01:01:57 -   1.17
 +++ lib/libc/stdlib/random.c27 Sep 2012 10:48:45 -
 @@ -35,6 +35,10 @@
  #include stdio.h
  #include stdlib.h
  #include unistd.h
 +#include thread_private.h
 +
 +static void srandom_unlocked(unsigned int);
 +static long random_unlocked(void);

  /*
   * random.c:
 @@ -186,8 +190,8 @@ static int rand_sep = SEP_3;
   * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
   * for default usage relies on values produced by this routine.
   */
 -void
 -srandom(unsigned int x)
 +static void
 +srandom_unlocked(unsigned int x)
  {
 int i;
 int32_t test;
 @@ -213,10 +217,18 @@ srandom(unsigned int x)
 fptr = state[rand_sep];
 rptr = state[0];
 for (i = 0; i  10 * rand_deg; i++)
 -   (void)random();
 +   (void)random_unlocked();
 }
  }

 +void
 +srandom(unsigned int x)
 +{
 +   _RANDOM_LOCK();
 +   srandom_unlocked(x);
 +   _RANDOM_UNLOCK();
 +}
 +
  /*
   * srandomdev:
   *
 @@ -273,12 +285,15 @@ initstate(u_int seed, char *arg_state, s
  {
 char *ostate 

[PATCH, TEST] Make functions in random.c thread safe

2012-09-28 Thread Alexey Suslikov
Hi.

With input from tedu@, guenther@ and others, below are:
1) test case;
2) backtrace for test case;
3) locking diff;
4) dmesg (amd64 GENERIC.MP built from 2012-09-28 CVS).

Diff introduces no changes to srandomdev(): correct me if I'm wrong,
but no mutex can be used since sysctl can sleep.

Rebuild and reinstall in src/lib/librthread and src/lib/libc after applying
the diff.

Expect test case (and Kannel port of course) not crashing after rebuild
and reinstall.

Cheers,
Alexey

1) test case.

#include pthread.h
#include stdio.h
#include stdlib.h
#include assert.h
#include unistd.h

#define NUM_THREADS1800

void *TaskCode(void *argument)
{
struct timeval  tv;

gettimeofday(tv, 0);
srandom((getpid()  16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);

return NULL;
}

int main(void)
{
pthread_t threads[NUM_THREADS];
int thread_args[NUM_THREADS];
int rc, i;

/* create all threads */
for (i=0; iNUM_THREADS; ++i) {
thread_args[i] = i;
rc = pthread_create(threads[i], NULL, TaskCode, (void *) 
thread_args[i]);
assert(0 == rc);
}

/* wait for all threads to complete */
for (i=0; iNUM_THREADS; ++i) {
rc = pthread_join(threads[i], NULL);
assert(0 == rc);
}

printf(Test srandom success\n);
exit(EXIT_SUCCESS);
}

2) backtrace for test case.

Program received signal SIGSEGV, Segmentation fault.
[Switching to thread 1030380]
0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
387 *fptr += *rptr;

(gdb) bt
#0  0x19d34d618f8e in random () at /usr/src/lib/libc/stdlib/random.c:387
#1  0x19d34d619169 in srandom (x=Variable x is not available.
) at /usr/src/lib/libc/stdlib/random.c:216
#2  0x19d14fe1 in TaskCode (argument=0x7f7ea004) at
test_srandom.c:14
#3  0x19d34999d11e in _rthread_start (v=Variable v is not available.
) at /usr/src/lib/librthread/rthread.c:122
#4  0x19d34d5f0f9b in __tfork_thread () at
/usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:75
Cannot access memory at address 0x19d344efb000

3) locking diff.

Index: lib/libc/include/thread_private.h
===
RCS file: /cvs/src/lib/libc/include/thread_private.h,v
retrieving revision 1.25
diff -u -p -r1.25 thread_private.h
--- lib/libc/include/thread_private.h   16 Oct 2011 06:29:56 -  1.25
+++ lib/libc/include/thread_private.h   27 Sep 2012 10:48:45 -
@@ -172,4 +172,16 @@ void   _thread_arc4_unlock(void);
_thread_arc4_unlock();\
} while (0)

+void   _thread_random_lock(void);
+void   _thread_random_unlock(void);
+
+#define _RANDOM_LOCK() do {\
+   if (__isthreaded)   \
+   _thread_random_lock();  \
+   } while (0)
+#define _RANDOM_UNLOCK()   do {\
+   if (__isthreaded)   \
+   _thread_random_unlock();\
+   } while (0)
+
 #endif /* _THREAD_PRIVATE_H_ */
Index: lib/libc/stdlib/random.c
===
RCS file: /cvs/src/lib/libc/stdlib/random.c,v
retrieving revision 1.17
diff -u -p -r1.17 random.c
--- lib/libc/stdlib/random.c1 Jun 2012 01:01:57 -   1.17
+++ lib/libc/stdlib/random.c27 Sep 2012 10:48:45 -
@@ -35,6 +35,10 @@
 #include stdio.h
 #include stdlib.h
 #include unistd.h
+#include thread_private.h
+
+static void srandom_unlocked(unsigned int);
+static long random_unlocked(void);

 /*
  * random.c:
@@ -186,8 +190,8 @@ static int rand_sep = SEP_3;
  * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
  * for default usage relies on values produced by this routine.
  */
-void
-srandom(unsigned int x)
+static void
+srandom_unlocked(unsigned int x)
 {
int i;
int32_t test;
@@ -213,10 +217,18 @@ srandom(unsigned int x)
fptr = state[rand_sep];
rptr = state[0];
for (i = 0; i  10 * rand_deg; i++)
-   (void)random();
+   (void)random_unlocked();
}
 }

+void
+srandom(unsigned int x)
+{
+   _RANDOM_LOCK();
+   srandom_unlocked(x);
+   _RANDOM_UNLOCK();
+}
+
 /*
  * srandomdev:
  *
@@ -273,12 +285,15 @@ initstate(u_int seed, char *arg_state, s
 {
char *ostate = (char *)(state[-1]);

+   _RANDOM_LOCK();
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-   if (n  BREAK_0)
+   if (n  BREAK_0) {
+