void * acqrel_thr(void *id)
{ int me = (int)(AO_PTRDIFF_T)id;
int i;
for (i = 0; i < NITERS; ++i) if (me & 1)
{
AO_t my_counter1; if (me != 1)
{
fprintf(stderr, "acqrel test: too many threads\n");
abort();
}
my_counter1 = AO_load(&counter1);
AO_store(&counter1, my_counter1 + 1);
AO_store_release_write(&counter2, my_counter1 + 1);
} else
{
AO_t my_counter1a, my_counter2a;
AO_t my_counter1b, my_counter2b;
my_counter2a = AO_load_acquire_read(&counter2);
my_counter1a = AO_load(&counter1); /* Redo this, to make sure that the second load of counter1 */ /* is not viewed as a common subexpression. */
my_counter2b = AO_load_acquire_read(&counter2);
my_counter1b = AO_load(&counter1); if (my_counter1a < my_counter2a)
{
fprintf(stderr, "Saw release store out of order: %lu < %lu\n",
(unsignedlong)my_counter1a, (unsignedlong)my_counter2a);
abort();
} if (my_counter1b < my_counter2b)
{
fprintf(stderr, "Saw release store out of order (bad CSE?): %lu < %lu\n",
(unsignedlong)my_counter1b, (unsignedlong)my_counter2b);
abort();
}
}
for (i = 0; i < NITERS/10; ++i)
{ while (AO_test_and_set_acquire(&lock) != AO_TS_CLEAR);
++locked_counter; if (locked_counter != 1)
{
fprintf(stderr, "Test and set failure 1, counter = %ld, id = %d\n",
(long)locked_counter, (int)(AO_PTRDIFF_T)id);
abort();
}
locked_counter *= 2;
locked_counter -= 1;
locked_counter *= 5;
locked_counter -= 4; if (locked_counter != 1)
{
fprintf(stderr, "Test and set failure 2, counter = %ld, id = %d\n",
(long)locked_counter, (int)(AO_PTRDIFF_T)id);
abort();
}
--locked_counter;
AO_CLEAR(&lock); /* Spend a bit of time outside the lock. */
do_junk();
} return0;
}
int test_and_set_test(void)
{ return locked_counter == 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.