8158 Want named threads API
[unleashed.git] / usr / src / lib / libdtrace / common / dt_pq.c
blob0cd556abd8f5be12be5eed12bce9c9d5ac0bf91e
1 /*
2 * CDDL HEADER START
4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
7 * 1.0 of the CDDL.
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
13 * CDDL HEADER END
17 * Copyright (c) 2012 by Delphix. All rights reserved.
20 #include <dtrace.h>
21 #include <dt_impl.h>
22 #include <dt_pq.h>
23 #include <assert.h>
26 * Create a new priority queue.
28 * size is the maximum number of items that will be stored in the priority
29 * queue at one time.
31 dt_pq_t *
32 dt_pq_init(dtrace_hdl_t *dtp, uint_t size, dt_pq_value_f value_cb, void *cb_arg)
34 dt_pq_t *p;
35 assert(size > 1);
37 if ((p = dt_zalloc(dtp, sizeof (dt_pq_t))) == NULL)
38 return (NULL);
40 p->dtpq_items = dt_zalloc(dtp, size * sizeof (p->dtpq_items[0]));
41 if (p->dtpq_items == NULL) {
42 dt_free(dtp, p);
43 return (NULL);
46 p->dtpq_hdl = dtp;
47 p->dtpq_size = size;
48 p->dtpq_last = 1;
49 p->dtpq_value = value_cb;
50 p->dtpq_arg = cb_arg;
52 return (p);
55 void
56 dt_pq_fini(dt_pq_t *p)
58 dtrace_hdl_t *dtp = p->dtpq_hdl;
60 dt_free(dtp, p->dtpq_items);
61 dt_free(dtp, p);
64 static uint64_t
65 dt_pq_getvalue(dt_pq_t *p, uint_t index)
67 void *item = p->dtpq_items[index];
68 return (p->dtpq_value(item, p->dtpq_arg));
71 void
72 dt_pq_insert(dt_pq_t *p, void *item)
74 uint_t i;
76 assert(p->dtpq_last < p->dtpq_size);
78 i = p->dtpq_last++;
79 p->dtpq_items[i] = item;
81 while (i > 1 && dt_pq_getvalue(p, i) < dt_pq_getvalue(p, i / 2)) {
82 void *tmp = p->dtpq_items[i];
83 p->dtpq_items[i] = p->dtpq_items[i / 2];
84 p->dtpq_items[i / 2] = tmp;
85 i /= 2;
90 * Return elements from the priority queue. *cookie should be zero when first
91 * called. Returns NULL when there are no more elements.
93 void *
94 dt_pq_walk(dt_pq_t *p, uint_t *cookie)
96 (*cookie)++;
97 if (*cookie >= p->dtpq_last)
98 return (NULL);
100 return (p->dtpq_items[*cookie]);
103 void *
104 dt_pq_pop(dt_pq_t *p)
106 uint_t i = 1;
107 void *ret;
109 assert(p->dtpq_last > 0);
111 if (p->dtpq_last == 1)
112 return (NULL);
114 ret = p->dtpq_items[1];
116 p->dtpq_last--;
117 p->dtpq_items[1] = p->dtpq_items[p->dtpq_last];
118 p->dtpq_items[p->dtpq_last] = NULL;
120 for (;;) {
121 uint_t lc = i * 2;
122 uint_t rc = i * 2 + 1;
123 uint_t c;
124 uint64_t v;
125 void *tmp;
127 if (lc >= p->dtpq_last)
128 break;
130 if (rc >= p->dtpq_last) {
131 c = lc;
132 v = dt_pq_getvalue(p, lc);
133 } else {
134 uint64_t lv = dt_pq_getvalue(p, lc);
135 uint64_t rv = dt_pq_getvalue(p, rc);
137 if (lv < rv) {
138 c = lc;
139 v = lv;
140 } else {
141 c = rc;
142 v = rv;
146 if (v >= dt_pq_getvalue(p, i))
147 break;
149 tmp = p->dtpq_items[i];
150 p->dtpq_items[i] = p->dtpq_items[c];
151 p->dtpq_items[c] = tmp;
153 i = c;
156 return (ret);