5 #include <mono/metadata/metadata.h>
6 #include <mono/utils/mono-threads.h>
7 #include <mono/utils/hazard-pointer.h>
8 #include <mono/utils/mono-linked-list-set.h>
9 #include <mono/utils/atomic.h>
11 static MonoLinkedListSet lls;
20 #define NUM_ITERS 1000000
24 MonoLinkedListSetNode node;
35 static node_t nodes [N];
38 mono_hazard_pointer_clear_all (MonoThreadHazardPointers *hp, int retain)
41 mono_hazard_pointer_clear (hp, 0);
43 mono_hazard_pointer_clear (hp, 1);
45 mono_hazard_pointer_clear (hp, 2);
51 node_t *node = (node_t *)n;
52 assert (node->state == STATE_BUSY);
53 node->state = STATE_OUT;
59 thread_data_t *thread_data = (thread_data_t *)arg;
60 MonoThreadHazardPointers *hp;
61 int skip = thread_data->skip;
65 mono_thread_info_register_small_id ();
67 hp = mono_hazard_pointer_get ();
70 for (j = 0; j < NUM_ITERS; ++j) {
71 switch (nodes [i].state) {
73 mono_thread_hazardous_try_free_some ();
76 if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
77 result = mono_lls_find (&lls, hp, i);
79 mono_hazard_pointer_clear_all (hp, -1);
81 result = mono_lls_insert (&lls, hp, &nodes [i].node);
82 mono_hazard_pointer_clear_all (hp, -1);
84 assert (nodes [i].state == STATE_BUSY);
85 nodes [i].state = STATE_IN;
87 ++thread_data->num_adds;
91 if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
92 result = mono_lls_find (&lls, hp, i);
94 assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
95 mono_hazard_pointer_clear_all (hp, -1);
97 result = mono_lls_remove (&lls, hp, &nodes [i].node);
98 mono_hazard_pointer_clear_all (hp, -1);
100 ++thread_data->num_removes;
116 main (int argc, char *argv [])
118 int primes [] = { 1, 2, 3, 5, 7, 11, 13, 17 };
119 thread_data_t thread_data [NUM_THREADS];
122 mono_metadata_init ();
124 mono_thread_info_init (0);
126 mono_lls_init (&lls, free_node);
128 for (i = 0; i < N; ++i) {
129 nodes [i].node.key = i;
130 nodes [i].state = STATE_OUT;
133 for (i = 0; i < NUM_THREADS; ++i) {
136 thread_data [i].num_adds = thread_data [i].num_removes = 0;
137 thread_data [i].skip = primes [i];
138 result = pthread_create (&thread_data [i].thread, NULL, worker, &thread_data [i]);
142 for (i = 0; i < NUM_THREADS; ++i) {
143 int result = pthread_join (thread_data [i].thread, NULL);
145 printf ("thread %d adds %d removes %d\n", i, thread_data [i].num_adds, thread_data [i].num_removes);