1 #include <sys/resource.h>
20 /* for mutex testing */
23 #include "portable_defns.h"
24 #include "set_queue_adt.h"
27 #define CREATE_N 1000000
29 #define SENTINEL_KEYMIN ( 1UL)
30 #define SENTINEL_KEYMAX (~0UL)
34 unsigned long secret_key;
35 unsigned long xxx[10];
49 /* lock-free object cache */
51 typedef int osi_mcas_obj_cache_t;
54 osi_mcas_obj_cache_create(osi_mcas_obj_cache_t * gc_id, size_t size)
56 *(int *)gc_id = gc_add_allocator(size + sizeof(int *));
60 osi_mcas_obj_cache_alloc(osi_mcas_obj_cache_t gc_id)
65 ptst = critical_enter();
66 obj = (void *)gc_alloc(ptst, gc_id);
72 osi_mcas_obj_cache_free(osi_mcas_obj_cache_t gc_id, void *obj)
76 ptst = critical_enter();
77 gc_free(ptst, (void *)obj, gc_id);
82 osi_mcas_obj_cache_destroy(osi_mcas_obj_cache_t gc_id)
88 /* lock-free object cache */
90 /* Key data type and comparison function */
92 harness_ulong_comp(const void *lhs, const void *rhs)
94 harness_ulong_t *l, *r;
96 l = (harness_ulong_t *) lhs;
97 r = (harness_ulong_t *) rhs;
99 /* todo: move to wrapper macro outside
102 if (lhs == (void *)SENTINEL_KEYMAX)
104 if (rhs == (void *)SENTINEL_KEYMAX)
107 if (lhs == (void *)SENTINEL_KEYMIN)
109 if (rhs == (void *)SENTINEL_KEYMIN)
113 if (l->key == r->key)
122 test_each_func(osi_set_t * l, setval_t v, void *arg)
126 osi_mcas_obj_cache_t gc_id;
129 traversal = *(int *)arg;
130 z = (harness_ulong_t *) v;
133 if (z->traversal == traversal)
136 if (z->key % 10 == 0) {
137 printf("SPONGEBOB would delete key %d: secret key: %d (t: %d) \n",
138 z->key, z->secret_key, z->traversal);
140 osi_cas_skip_remove(l, z);
141 osi_mcas_obj_cache_free(gc_id, z);
143 printf("SQUAREPANTS still here key %d: secret key: %d (t: %d) \n",
144 z->key, z->secret_key, z->traversal);
148 z->traversal = traversal;
152 test_each_func_2(osi_set_t * l, setval_t v, void *arg)
158 traversal = *(int *)arg;
159 z = (harness_ulong_t *) v;
161 if (z->traversal == traversal)
164 printf("SQUAREPANTS still here key %d: secret key: %d\n",
165 z->key, z->secret_key);
167 z->traversal = traversal;
171 thread_do_test(void *arg)
173 int ix, ix2, six, eix, sv;
174 harness_ulong_t *node, *node2, *snode;
178 six = CREATE_N / 4 * sv;
179 eix = six + CREATE_N / 4;
181 printf("Starting thread with %d %d %d\n", sv, six, eix);
183 /* Allocate nodes and insert in skip queue */
185 for (; six < eix; ++six) {
188 node = (harness_ulong_t *) malloc(sizeof(harness_ulong_t));
189 memset(node, 0, sizeof(harness_ulong_t));
191 node->secret_key = 2 * six;
192 printf("thread %d insert: %d key: %d secret: %d\n", sv, node,
193 node->key, node->secret_key);
194 osi_cas_skip_update(shared.set, node, node, 1);
196 #if 0 /* reuse package test */
198 node2 = (harness_ulong_t *) malloc(sizeof(harness_ulong_t));
199 memset(node2, 0, sizeof(harness_ulong_t));
201 node2->secret_key = 3 * six;
202 printf("thread %d insert: %d key: %d secret: %d\n", sv, node2,
203 node2->key, node2->secret_key);
204 osi_cas_skip_update(shared.set2, node2, node2, 1);
208 snode = (harness_ulong_t *) malloc(sizeof(harness_ulong_t));
213 for (ix = 0; ix < CREATE_N; ix += 1) {
215 node = osi_cas_skip_lookup(shared.set, snode);
217 printf("thread %d searched set(1) for and found: key: "
218 "%d secret_key: %d\n",
219 sv, node->key, node->secret_key);
221 printf("thread %d searched set(1) for and didn't find: %d\n",
225 node = osi_cas_skip_lookup(shared.set2, snode);
227 printf("thread %d searched set(2) for and found: key: "
228 "%d secret_key: %d\n",
229 sv, node->key, node->secret_key);
231 printf("thread %d searched set(2) for and didn't find: %d\n",
237 } while (ix2 < 10000);
245 /* help test atomic inc, dec */
247 typedef long osi_atomic_t;
249 #define osi_atomic_inc(x) \
255 #define osi_atomic_dec(x) \
263 main(int argc, char **argv)
267 harness_ulong_t *node, *node2, *snode;
268 osi_mcas_obj_cache_t gc_id, gc2_id;
270 printf("Starting ADT Test\n");
272 /* do this once, 1st thread */
273 _init_ptst_subsystem();
274 _init_gc_subsystem();
275 _init_osi_cas_skip_subsystem();
277 osi_mcas_obj_cache_create(&gc_id, sizeof(harness_ulong_t));
278 osi_mcas_obj_cache_create(&gc2_id, sizeof(harness_ulong_t));
280 shared.set = osi_cas_skip_alloc(&harness_ulong_comp);
281 shared.set2 = osi_cas_skip_alloc(&harness_ulong_comp);
283 /* just insert and iterate */
285 for (ix = 0; ix < CREATE_N; ++ix) {
288 node = (harness_ulong_t *) osi_mcas_obj_cache_alloc(gc_id);
289 pthread_mutex_init(&node->lock, NULL);
291 /* and pound on collector 2 */
292 node2 = (harness_ulong_t *) osi_mcas_obj_cache_alloc(gc2_id);
296 node->secret_key = 2 * ix;
297 printf("insert: %d key: %d secret: %d\n", node,
298 node->key, node->secret_key);
299 osi_cas_skip_update(shared.set, node, node, 1);
302 snode = (harness_ulong_t *) osi_mcas_obj_cache_alloc(gc_id);
303 snode->gc_id = gc_id;
305 node = osi_cas_skip_lookup(shared.set, snode);
307 printf("searched set(1) for and found: key: "
308 "%d secret_key: %d\n", node->key, node->secret_key);
310 printf("searched set(1) for and didn't find: %d\n", snode->key);
315 /* traversal is used to avoid acting on duplicate references (which
316 * are an artifact of skip list implementation; assumes only one
317 * thread may be in set_for_each, as implemented */
321 osi_cas_skip_for_each(shared.set, &test_each_func, &traversal);
327 osi_cas_skip_for_each(shared.set, &test_each_func_2, &traversal);
329 /* test osi_atomic_inc */
335 for (ai = 0, a_ix = 0; a_ix < 10; ++a_ix) {
340 printf("ai is: %d\n", ai);
343 osi_mcas_obj_cache_free(gc_id, node);