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:
parent
593f022515
commit
030782e1a8
@ -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) $<
|
||||
|
||||
|
@ -109,6 +109,7 @@ QTOBJS= \
|
||||
qtextstream.obj \
|
||||
qdatastream.obj \
|
||||
quuid.obj \
|
||||
qrandom.obj \
|
||||
qsettings.obj \
|
||||
qvariant.obj \
|
||||
qsettings_win.obj \
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user