All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Bernard Normier" <bernard@zeroc.com>
To: "Jan Engelhardt" <jengelh@linux01.gwdg.de>
Cc: <linux-kernel@vger.kernel.org>
Subject: Re: Concurrent access to /dev/urandom
Date: Sun, 28 Nov 2004 15:58:03 -0500	[thread overview]
Message-ID: <02c001c4d58c$f6476bb0$6400a8c0@centrino> (raw)
In-Reply-To: Pine.LNX.4.53.0411272220530.26852@yvahk01.tjqt.qr

>>> Rule of thumb: Post the smallest possible code that shows the problem.
>>Will do next time!
>
> That would be great, because it could show that urandom is missing a lock
> somewhere.

Here is a smaller version (102 lines vs 173 before). It's difficult to get 
something very very small since I need to start a few threads.

Bernard

#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>

#include <set>
#include <iostream>
using namespace std;

// Each thread will generate keyCount keys
static int threadCount = 3;
static int keyCount = 1000000 / threadCount;

// When not defined, all threads read /dev/urandom concurrently
// #define SERIALIZE_READS 1

struct Key
{
    long long high;
    long long low;

    bool operator<(const Key& rhs) const
    {
        return high < rhs.high || (high == rhs.high && low < rhs.low);
    }
};

static set<Key> keySet;
static pthread_mutex_t keySetMutex = PTHREAD_MUTEX_INITIALIZER;

extern "C" void* readRandom(void*)
{
    for(int i = 0; i < keyCount; ++i)
    {
        int fd = open("/dev/urandom", O_RDONLY);
        assert(fd != -1);

#ifdef SERIALIZE_READS
        int err = pthread_mutex_lock(&keySetMutex);
        assert(err == 0);
#endif
        size_t index = 0;
        char buffer[sizeof(Key)];

        while(index != sizeof(Key))
        {
            ssize_t bytesRead = read(fd, buffer + index, sizeof(Key) - 
index);

            if(bytesRead == -1)
            {
                if(errno != EINTR)
                {
                    close(fd);
                    return reinterpret_cast<void*>(-1);
                }
            }
            else
            {
                index += bytesRead;
            }
        }

        close(fd);

#ifndef SERIALIZE_READS
        int err = pthread_mutex_lock(&keySetMutex);
        assert(err == 0);
#endif
        pair<set<Key>::iterator, bool> result = 
keySet.insert(reinterpret_cast<Key&>(buffer));
        if(!result.second)
        {
            cerr << "Found duplicate!" << endl;
        }
        err = pthread_mutex_unlock(&keySetMutex);
        assert(err == 0);
    }

    return 0;
}

int main(int argc, char* argv[])
{
    pthread_t* threads = new pthread_t[threadCount];
    for(int i = 0; i < threadCount; ++i)
    {
        int err = pthread_create(&threads[i], 0, readRandom, 0);
        assert(err == 0);
    }
    for(int i = 0; i < threadCount; ++i)
    {
        void* threadStatus;
        int err = pthread_join(threads[i], &threadStatus);
        assert(err == 0);
        assert(threadStatus == 0);
    }

    delete[] threads;
    return 0;
}

// build with  g++ -D_REENTRANT  -o utest utest.cpp -lpthread




  reply	other threads:[~2004-11-28 20:58 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-27 20:45 Concurrent access to /dev/urandom Bernard Normier
2004-11-27 20:56 ` Jan Engelhardt
2004-11-27 21:15   ` Bernard Normier
2004-11-27 21:22     ` Jan Engelhardt
2004-11-28 20:58       ` Bernard Normier [this message]
2004-12-07 23:41         ` Bernard Normier
2004-12-08  1:28           ` Theodore Ts'o
2004-12-08  1:56             ` Bernard Normier
2004-12-08 19:21               ` Theodore Ts'o
2004-12-08 20:15                 ` Bernard Normier
2004-12-08 21:56                 ` Matt Mackall
2004-12-09  1:57                   ` Theodore Ts'o
2004-12-09  2:46                     ` andyliu
2004-12-09  4:55                       ` Matt Mackall
2004-12-09  2:58                     ` Matt Mackall
2004-12-09 21:29                     ` Matt Mackall
2004-12-10  4:47                       ` Matt Mackall
2004-12-10 16:35                         ` Theodore Ts'o
2004-12-10 18:28                           ` Matt Mackall
2004-12-10 21:28                             ` Theodore Ts'o
2004-12-10 22:23                               ` Matt Mackall
2004-12-11  0:22                                 ` Adam Heath
2004-12-11  1:10                                   ` Matt Mackall
2004-12-11 17:33                                   ` Theodore Ts'o
2004-12-11 19:58                                     ` Adam Heath
2004-12-11 20:40                                       ` Matt Mackall
2004-12-12 16:19                                     ` Pavel Machek
2004-12-11  0:19                               ` Adam Heath
2004-12-09  3:10               ` David Lang
2004-12-09  4:52                 ` Matt Mackall
2004-12-09  6:36                 ` Theodore Ts'o
2004-11-29 22:47 ` Jon Masters
2004-11-29 23:14   ` Bernard Normier
2004-11-29 23:43     ` Sven-Haegar Koch
2004-11-30  2:31       ` David Schwartz
2004-11-30  4:14         ` Kyle Moffett
2004-11-30  8:23           ` Jan Engelhardt
2004-11-30 18:50             ` David Schwartz
2004-11-29 23:42   ` David Wagner

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='02c001c4d58c$f6476bb0$6400a8c0@centrino' \
    --to=bernard@zeroc.com \
    --cc=jengelh@linux01.gwdg.de \
    --cc=linux-kernel@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.