Skip to content

Commit 7cdadcd

Browse files
committed
On some systems, uniqid() is critically slow.
If available, use uuidgen() system call instead of a loop on gettimeofday(), that improves performances lot.
1 parent f4954df commit 7cdadcd

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ AC_CHECK_FUNCS(m4_normalize([
588588
unsetenv
589589
usleep
590590
utime
591+
uuidgen
591592
vasprintf
592593
]))
593594

ext/standard/uniqid.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,44 @@
3131
#include <sys/time.h>
3232
#endif
3333

34+
#ifdef HAVE_UUIDGEN
35+
#include <sys/types.h>
36+
#include <sys/uuid.h>
37+
#endif
38+
3439
#include "ext/random/php_random.h"
3540
#include "ext/random/php_random_csprng.h"
3641

37-
#ifdef HAVE_GETTIMEOFDAY
42+
#ifdef HAVE_UUIDGEN
43+
/* {{{ Generates a unique ID */
44+
PHP_FUNCTION(uniqid)
45+
{
46+
char *prefix = "";
47+
bool more_entropy = 0;
48+
zend_string *uniqid;
49+
size_t prefix_len = 0;
50+
struct uuid uuid;
51+
int *n = (int *)&uuid;
52+
53+
ZEND_PARSE_PARAMETERS_START(0, 2)
54+
Z_PARAM_OPTIONAL
55+
Z_PARAM_STRING(prefix, prefix_len)
56+
Z_PARAM_BOOL(more_entropy)
57+
ZEND_PARSE_PARAMETERS_END();
58+
59+
(void)uuidgen(&uuid, 1);
60+
61+
if (more_entropy) {
62+
n[1] &= 0xffffff;
63+
uniqid = strpprintf(0, "%s%08x%06x.%08x", prefix, n[0], n[1], n[2]);
64+
} else {
65+
n[1] &= 0xfffff;
66+
uniqid = strpprintf(0, "%s%08x%05x", prefix, n[0], n[1]);
67+
}
68+
69+
RETURN_STR(uniqid);
70+
}
71+
#elif HAVE_GETTIMEOFDAY
3872
ZEND_TLS struct timeval prev_tv = { 0, 0 };
3973

4074
/* {{{ Generates a unique ID */
@@ -53,6 +87,24 @@ PHP_FUNCTION(uniqid)
5387
Z_PARAM_BOOL(more_entropy)
5488
ZEND_PARSE_PARAMETERS_END();
5589

90+
#ifdef __NetBSD__
91+
struct uuid uuid;
92+
int *n = (int *)&uuid;
93+
94+
/* Use faster uuidgen() if available */
95+
(void)uuidgen(&uuid, 1);
96+
97+
if (more_entropy) {
98+
n[1] &= 0xffffff;
99+
uniqid = strpprintf(0, "%s%08x%06x.%08x", prefix, n[0], n[1], n[2]);
100+
} else {
101+
n[1] &= 0xfffff;
102+
uniqid = strpprintf(0, "%s%08x%05x", prefix, n[0], n[1]);
103+
}
104+
105+
RETURN_STR(uniqid);
106+
#endif
107+
56108
/* This implementation needs current microsecond to change,
57109
* hence we poll time until it does. This is much faster than
58110
* calling usleep(1) which may cause the kernel to schedule

0 commit comments

Comments
 (0)