summaryrefslogtreecommitdiff
path: root/src/cairo-skiplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-skiplist.c')
-rw-r--r--src/cairo-skiplist.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index b08453b0..d03a6bfc 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -91,20 +91,22 @@ _cairo_skip_list_fini (cairo_skip_list_t *list)
static int
random_level (void)
{
- int level = 0;
/* tricky bit -- each bit is '1' 75% of the time.
* This works because we only use the lower MAX_LEVEL
* bits, and MAX_LEVEL < 16 */
uint32_t bits = hars_petruska_f54_1_random ();
- bits |= bits >> 16;
-
- while (++level < MAX_LEVEL)
- {
- if (bits & 1)
- break;
+#if HAVE_FFS
+ return ffs (-(1<<MAX_LEVEL) | bits | bits >> 16);
+#else
+ int level = 1;
+
+ bits |= -(1<<MAX_LEVEL) | bits >> 16;
+ while ((bits & 1) == 0) {
+ level++;
bits >>= 1;
}
return level;
+#endif
}
static void *
@@ -181,7 +183,7 @@ _cairo_skip_list_insert (cairo_skip_list_t *list, void *data, int unique)
}
data_and_elt = alloc_node_for_level (list, level);
- if (data_and_elt == NULL) {
+ if (unlikely (data_and_elt == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}