Move qrand() & qsrand() to qrandom.cpp

Now that we have the file, may as well consolidate

Change-Id: Icd0e0d4b27cb4e5eb892fffd14b51d3e701c6a94
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2017-04-13 17:50:05 -07:00
parent 593f022515
commit 030782e1a8
5 changed files with 151 additions and 137 deletions

View File

@ -18,7 +18,7 @@ OBJS = \
#qt code (please keep in order matching DEPEND_SRC)
QOBJS = \
qtextcodec.o qutfcodec.o \
qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o \
qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o qrandom.o \
qabstractfileengine.o qbuffer.o qdatastream.o qdebug.o \
qdir.o qdiriterator.o \
qfile.o qfiledevice.o qfileinfo.o qfilesystemengine.o \
@ -74,6 +74,7 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \
$(SOURCE_PATH)/src/corelib/global/qnumeric.cpp \
$(SOURCE_PATH)/src/corelib/global/qoperatingsystemversion.cpp \
$(SOURCE_PATH)/src/corelib/global/qrandom.cpp \
$(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \
$(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \
$(SOURCE_PATH)/src/corelib/io/qdatastream.cpp \
@ -83,6 +84,7 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/io/qfile.cpp \
$(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \
$(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp \
$(SOURCE_PATH)/src/corelib/global/qrandom.cpp \
$(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp \
$(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp \
$(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp \
@ -276,6 +278,9 @@ qlibraryinfo_final.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(BUILD
qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qrandom.o: $(SOURCE_PATH)/src/corelib/global/qrandom.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qsettings_mac.o: $(SOURCE_PATH)/src/corelib/io/qsettings_mac.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
@ -297,6 +302,9 @@ qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qrandom.o: $(SOURCE_PATH)/src/corelib/global/qrandom.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qrandom.cpp
qarraydata.o: $(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<

View File

@ -109,6 +109,7 @@ QTOBJS= \
qtextstream.obj \
qdatastream.obj \
quuid.obj \
qrandom.obj \
qsettings.obj \
qvariant.obj \
qsettings_win.obj \

View File

@ -42,7 +42,6 @@
#include "qstring.h"
#include "qvector.h"
#include "qlist.h"
#include "qthreadstorage.h"
#include "qdir.h"
#include "qdatetime.h"
#include "qoperatingsystemversion.h"
@ -3472,140 +3471,6 @@ bool qunsetenv(const char *varName)
#endif
}
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
# if defined(Q_OS_INTEGRITY) && defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 500)
// older versions of INTEGRITY used a long instead of a uint for the seed.
typedef long SeedStorageType;
# else
typedef uint SeedStorageType;
# endif
typedef QThreadStorage<SeedStorageType *> SeedStorage;
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
#elif defined(Q_OS_ANDROID)
typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
#endif
/*!
\relates <QtGlobal>
\since 4.2
Thread-safe version of the standard C++ \c srand() function.
Sets the argument \a seed to be used to generate a new random number sequence of
pseudo random integers to be returned by qrand().
The sequence of random numbers generated is deterministic per thread. For example,
if two threads call qsrand(1) and subsequently call qrand(), the threads will get
the same random number sequence.
\sa qrand(), QRandomGenerator
*/
void qsrand(uint seed)
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
SeedStorage *seedStorage = randTLS();
if (seedStorage) {
SeedStorageType *pseed = seedStorage->localData();
if (!pseed)
seedStorage->setLocalData(pseed = new SeedStorageType);
*pseed = seed;
} else {
//global static seed storage should always exist,
//except after being deleted by QGlobalStaticDeleter.
//But since it still can be called from destructor of another
//global static object, fallback to srand(seed)
srand(seed);
}
#elif defined(Q_OS_ANDROID)
if (randomTLS->hasLocalData()) {
randomTLS->localData().callMethod<void>("setSeed", "(J)V", jlong(seed));
return;
}
QJNIObjectPrivate random("java/util/Random",
"(J)V",
jlong(seed));
if (!random.isValid()) {
srand(seed);
return;
}
randomTLS->setLocalData(random);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
// this is also valid for QT_NO_THREAD
srand(seed);
#endif
}
/*!
\relates <QtGlobal>
\since 4.2
Thread-safe version of the standard C++ \c rand() function.
Returns a value between 0 and \c RAND_MAX (defined in \c <cstdlib> and
\c <stdlib.h>), the next number in the current sequence of pseudo-random
integers.
Use \c qsrand() to initialize the pseudo-random number generator with a
seed value. Seeding must be performed at least once on each thread. If that
step is skipped, then the sequence will be pre-seeded with a constant
value.
\sa qsrand(), QRandomGenerator
*/
int qrand()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
SeedStorage *seedStorage = randTLS();
if (seedStorage) {
SeedStorageType *pseed = seedStorage->localData();
if (!pseed) {
seedStorage->setLocalData(pseed = new SeedStorageType);
*pseed = 1;
}
return rand_r(pseed);
} else {
//global static seed storage should always exist,
//except after being deleted by QGlobalStaticDeleter.
//But since it still can be called from destructor of another
//global static object, fallback to rand()
return rand();
}
#elif defined(Q_OS_ANDROID)
AndroidRandomStorage *randomStorage = randomTLS();
if (!randomStorage)
return rand();
if (randomStorage->hasLocalData()) {
return randomStorage->localData().callMethod<jint>("nextInt",
"(I)I",
RAND_MAX);
}
QJNIObjectPrivate random("java/util/Random",
"(J)V",
jlong(1));
if (!random.isValid())
return rand();
randomStorage->setLocalData(random);
return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
// this is also valid for QT_NO_THREAD
return rand();
#endif
}
/*!
\macro forever
\relates <QtGlobal>

View File

@ -42,6 +42,7 @@
#include "qrandom.h"
#include "qrandom_p.h"
#include <qthreadstorage.h>
#if QT_HAS_INCLUDE(<random>)
# include <random>
@ -62,6 +63,10 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
}
#endif
#if defined(Q_OS_ANDROID)
# include <private/qjni_p.h>
#endif
QT_BEGIN_NAMESPACE
namespace {
@ -231,7 +236,7 @@ static Q_NEVER_INLINE void fill(void *buffer, void *bufferEnd)
quint32 *ptr = reinterpret_cast<quint32 *>(buffer);
quint32 * const end = reinterpret_cast<quint32 *>(bufferEnd);
#if defined(Q_COMPILER_THREAD_LOCAL)
#if defined(Q_COMPILER_THREAD_LOCAL) && !defined(QT_BOOTSTRAPPED)
if (SystemRandom::EfficientBufferFill && (end - ptr) < ThreadState::BufferCount
&& uint(qt_randomdevice_control) == 0) {
thread_local ThreadState state;
@ -724,4 +729,138 @@ void QRandomGenerator::fillRange_helper(void *buffer, void *bufferEnd)
fill(buffer, bufferEnd);
}
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
# if defined(Q_OS_INTEGRITY) && defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 500)
// older versions of INTEGRITY used a long instead of a uint for the seed.
typedef long SeedStorageType;
# else
typedef uint SeedStorageType;
# endif
typedef QThreadStorage<SeedStorageType *> SeedStorage;
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
#elif defined(Q_OS_ANDROID)
typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
#endif
/*!
\relates <QtGlobal>
\since 4.2
Thread-safe version of the standard C++ \c srand() function.
Sets the argument \a seed to be used to generate a new random number sequence of
pseudo random integers to be returned by qrand().
The sequence of random numbers generated is deterministic per thread. For example,
if two threads call qsrand(1) and subsequently call qrand(), the threads will get
the same random number sequence.
\sa qrand(), QRandomGenerator
*/
void qsrand(uint seed)
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
SeedStorage *seedStorage = randTLS();
if (seedStorage) {
SeedStorageType *pseed = seedStorage->localData();
if (!pseed)
seedStorage->setLocalData(pseed = new SeedStorageType);
*pseed = seed;
} else {
//global static seed storage should always exist,
//except after being deleted by QGlobalStaticDeleter.
//But since it still can be called from destructor of another
//global static object, fallback to srand(seed)
srand(seed);
}
#elif defined(Q_OS_ANDROID)
if (randomTLS->hasLocalData()) {
randomTLS->localData().callMethod<void>("setSeed", "(J)V", jlong(seed));
return;
}
QJNIObjectPrivate random("java/util/Random",
"(J)V",
jlong(seed));
if (!random.isValid()) {
srand(seed);
return;
}
randomTLS->setLocalData(random);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
// this is also valid for QT_NO_THREAD
srand(seed);
#endif
}
/*!
\relates <QtGlobal>
\since 4.2
Thread-safe version of the standard C++ \c rand() function.
Returns a value between 0 and \c RAND_MAX (defined in \c <cstdlib> and
\c <stdlib.h>), the next number in the current sequence of pseudo-random
integers.
Use \c qsrand() to initialize the pseudo-random number generator with a
seed value. Seeding must be performed at least once on each thread. If that
step is skipped, then the sequence will be pre-seeded with a constant
value.
\sa qsrand(), QRandomGenerator
*/
int qrand()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
SeedStorage *seedStorage = randTLS();
if (seedStorage) {
SeedStorageType *pseed = seedStorage->localData();
if (!pseed) {
seedStorage->setLocalData(pseed = new SeedStorageType);
*pseed = 1;
}
return rand_r(pseed);
} else {
//global static seed storage should always exist,
//except after being deleted by QGlobalStaticDeleter.
//But since it still can be called from destructor of another
//global static object, fallback to rand()
return rand();
}
#elif defined(Q_OS_ANDROID)
AndroidRandomStorage *randomStorage = randomTLS();
if (!randomStorage)
return rand();
if (randomStorage->hasLocalData()) {
return randomStorage->localData().callMethod<jint>("nextInt",
"(I)I",
RAND_MAX);
}
QJNIObjectPrivate random("java/util/Random",
"(J)V",
jlong(1));
if (!random.isValid())
return rand();
randomStorage->setLocalData(random);
return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
// this is also valid for QT_NO_THREAD
return rand();
#endif
}
QT_END_NAMESPACE

View File

@ -29,6 +29,7 @@ SOURCES += \
../../corelib/global/qmalloc.cpp \
../../corelib/global/qnumeric.cpp \
../../corelib/global/qoperatingsystemversion.cpp \
../../corelib/global/qrandom.cpp \
../../corelib/io/qabstractfileengine.cpp \
../../corelib/io/qbuffer.cpp \
../../corelib/io/qdatastream.cpp \