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 (mono_atomic_cas_i32 (&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 (mono_atomic_cas_i32 (&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
;
119 test_mono_linked_list_set_main (void);
122 test_mono_linked_list_set_main (void)
124 int primes
[] = { 1, 2, 3, 5, 7, 11, 13, 17 };
125 thread_data_t thread_data
[NUM_THREADS
];
128 mono_metadata_init ();
130 mono_thread_info_init (0);
132 mono_lls_init (&lls
, free_node
);
134 for (i
= 0; i
< N
; ++i
) {
135 nodes
[i
].node
.key
= i
;
136 nodes
[i
].state
= STATE_OUT
;
139 for (i
= 0; i
< NUM_THREADS
; ++i
) {
142 thread_data
[i
].num_adds
= thread_data
[i
].num_removes
= 0;
143 thread_data
[i
].skip
= primes
[i
];
144 result
= pthread_create (&thread_data
[i
].thread
, NULL
, worker
, &thread_data
[i
]);
148 for (i
= 0; i
< NUM_THREADS
; ++i
) {
149 int result
= pthread_join (thread_data
[i
].thread
, NULL
);
151 printf ("thread %d adds %d removes %d\n", i
, thread_data
[i
].num_adds
, thread_data
[i
].num_removes
);