diff options
Diffstat (limited to 'src/cairo-skiplist.c')
-rw-r--r-- | src/cairo-skiplist.c | 18 |
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; } |