static void* worker (void *arg) { thread_data_t *thread_data = arg; MonoThreadHazardPointers *hp; int skip = thread_data->skip; int i, j; gboolean result; mono_thread_info_register_small_id (); hp = mono_hazard_pointer_get (); i = 0; for (j = 0; j < NUM_ITERS; ++j) { switch (nodes [i].state) { case STATE_BUSY: mono_thread_hazardous_try_free_some (); break; case STATE_OUT: if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) { result = mono_lls_find (&lls, hp, i); assert (!result); mono_hazard_pointer_clear_all (hp, -1); result = mono_lls_insert (&lls, hp, &nodes [i].node); mono_hazard_pointer_clear_all (hp, -1); assert (nodes [i].state == STATE_BUSY); nodes [i].state = STATE_IN; ++thread_data->num_adds; } break; case STATE_IN: if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) { result = mono_lls_find (&lls, hp, i); assert (result); assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node); mono_hazard_pointer_clear_all (hp, -1); result = mono_lls_remove (&lls, hp, &nodes [i].node); mono_hazard_pointer_clear_all (hp, -1); ++thread_data->num_removes; } break; default: assert (FALSE); } i += skip; if (i >= N) i -= N; } return NULL; }
static gboolean mono_thread_info_insert (MonoThreadInfo *info) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info)) { mono_hazard_pointer_clear_all (hp, -1); return FALSE; } mono_hazard_pointer_clear_all (hp, -1); return TRUE; }