Path: blob/main/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pq.c
39562 views
/*1* CDDL HEADER START2*3* This file and its contents are supplied under the terms of the4* Common Development and Distribution License ("CDDL"), version 1.0.5* You may only use this file in accordance with the terms of version6* 1.0 of the CDDL.7*8* A full copy of the text of the CDDL should have accompanied this9* source. A copy of the CDDL is also available via the Internet at10* http://www.illumos.org/license/CDDL.11*12* CDDL HEADER END13*/1415/*16* Copyright (c) 2012 by Delphix. All rights reserved.17*/1819#include <dtrace.h>20#include <dt_impl.h>21#include <dt_pq.h>22#include <assert.h>2324/*25* Create a new priority queue.26*27* size is the maximum number of items that will be stored in the priority28* queue at one time.29*/30dt_pq_t *31dt_pq_init(dtrace_hdl_t *dtp, uint_t size, dt_pq_value_f value_cb, void *cb_arg)32{33dt_pq_t *p;34assert(size > 1);3536if ((p = dt_zalloc(dtp, sizeof (dt_pq_t))) == NULL)37return (NULL);3839p->dtpq_items = dt_zalloc(dtp, (size + 1) * sizeof (p->dtpq_items[0]));40if (p->dtpq_items == NULL) {41dt_free(dtp, p);42return (NULL);43}4445p->dtpq_hdl = dtp;46p->dtpq_size = size;47p->dtpq_last = 1;48p->dtpq_value = value_cb;49p->dtpq_arg = cb_arg;5051return (p);52}5354void55dt_pq_fini(dt_pq_t *p)56{57dtrace_hdl_t *dtp = p->dtpq_hdl;5859dt_free(dtp, p->dtpq_items);60dt_free(dtp, p);61}6263static uint64_t64dt_pq_getvalue(dt_pq_t *p, uint_t index)65{66void *item = p->dtpq_items[index];67return (p->dtpq_value(item, p->dtpq_arg));68}6970void71dt_pq_insert(dt_pq_t *p, void *item)72{73uint_t i;7475i = p->dtpq_last++;76assert(i <= p->dtpq_size);7778p->dtpq_items[i] = item;7980while (i > 1 && dt_pq_getvalue(p, i) < dt_pq_getvalue(p, i / 2)) {81void *tmp = p->dtpq_items[i];82p->dtpq_items[i] = p->dtpq_items[i / 2];83p->dtpq_items[i / 2] = tmp;84i /= 2;85}86}8788/*89* Return elements from the priority queue. *cookie should be zero when first90* called. Returns NULL when there are no more elements.91*/92void *93dt_pq_walk(dt_pq_t *p, uint_t *cookie)94{95(*cookie)++;96if (*cookie >= p->dtpq_last)97return (NULL);9899return (p->dtpq_items[*cookie]);100}101102void *103dt_pq_pop(dt_pq_t *p)104{105uint_t i = 1;106void *ret;107108assert(p->dtpq_last > 0);109110if (p->dtpq_last == 1)111return (NULL);112113ret = p->dtpq_items[1];114115p->dtpq_last--;116p->dtpq_items[1] = p->dtpq_items[p->dtpq_last];117p->dtpq_items[p->dtpq_last] = NULL;118119for (;;) {120uint_t lc = i * 2;121uint_t rc = i * 2 + 1;122uint_t c;123uint64_t v;124void *tmp;125126if (lc >= p->dtpq_last)127break;128129if (rc >= p->dtpq_last) {130c = lc;131v = dt_pq_getvalue(p, lc);132} else {133uint64_t lv = dt_pq_getvalue(p, lc);134uint64_t rv = dt_pq_getvalue(p, rc);135136if (lv < rv) {137c = lc;138v = lv;139} else {140c = rc;141v = rv;142}143}144145if (v >= dt_pq_getvalue(p, i))146break;147148tmp = p->dtpq_items[i];149p->dtpq_items[i] = p->dtpq_items[c];150p->dtpq_items[c] = tmp;151152i = c;153}154155return (ret);156}157158159