int main () { vy_atomic_begin(); vy_assume(lock); lock = false; vy_spawn(writer); vy_atomic_end(); vy_atomic_begin(); vy_join(writer); lock = true; vy_atomic_end(); if (i == 0) { vy_atomic_begin(); increment_i(); vy_assume(lock); lock= false; vy_spawn(reader); vy_atomic_end(); } else if (i >= 1) { vy_atomic_begin(); increment_i(); vy_spawn(reader); vy_atomic_end(); } return 0; }
int main(int argc, char* argv[]) { int which = 0; data_t *heap_data = (data_t *)malloc(sizeof(data_t)); if (argc >= 2) { which = atoi(argv[1]); } init(&global_data); init(heap_data); switch(which) { case 0: cilk_spawn increment_i(&global_data); // write, read race mult_double(&global_data); cilk_sync; assert(__cilksan_error_count() == 3); break; case 1: cilk_spawn mult_double(&global_data); increment_i(&global_data); // write, read race cilk_sync; assert(__cilksan_error_count() == 3); break; case 2: cilk_spawn mult_double(&global_data); update_str(&global_data, 3, 8); // read, write race cilk_sync; assert(__cilksan_error_count() == 2); break; case 3: cilk_spawn increment_i(&global_data); // write, read race read_double(&global_data); cilk_sync; assert(__cilksan_error_count() == 1); break; case 4: cilk_spawn read_double(&global_data); increment_i(&global_data); // read, write race cilk_sync; assert(__cilksan_error_count() == 1); break; case 5: cilk_spawn read_double(&global_data); update_str(&global_data, 3, 8); // read, write race cilk_sync; assert(__cilksan_error_count() == 1); break; case 6: cilk_spawn read_str(&global_data, 2, 4); update_str(&global_data, 3, 8); // read, write race cilk_sync; assert(__cilksan_error_count() == 1); break; case 7: cilk_spawn increment_i(heap_data); // write, read race mult_double(heap_data); cilk_sync; assert(__cilksan_error_count() == 3); break; case 8: cilk_spawn mult_double(heap_data); increment_i(heap_data); // write, read race cilk_sync; assert(__cilksan_error_count() == 3); break; case 9: cilk_spawn mult_double(heap_data); update_str(heap_data, 3, 8); // write, write race cilk_sync; assert(__cilksan_error_count() == 2); break; case 10: cilk_spawn increment_i(heap_data); // write, read race read_double(heap_data); cilk_sync; assert(__cilksan_error_count() == 1); break; case 11: cilk_spawn read_double(heap_data); increment_i(heap_data); // read, write race cilk_sync; // to be sure that compiler doesn't optimize it away. global_int = heap_data->i; assert(__cilksan_error_count() == 1); break; case 12: cilk_spawn read_double(heap_data); update_str(heap_data, 3, 8); // read, write race cilk_sync; assert(__cilksan_error_count() == 1); break; case 13: cilk_spawn update_str(heap_data, 8, 11); read_str(heap_data, 10, 12); // write, read race cilk_sync; assert(__cilksan_error_count() == 1); break; case 14: cilk_spawn update_str(&global_data, 8, 12); // no race mult_double(&global_data); cilk_sync; assert(__cilksan_error_count() == 0); break; case 15: cilk_spawn update_str(&global_data, 4, 12); // no race read_i(&global_data); cilk_sync; assert(__cilksan_error_count() == 0); break; case 16: cilk_spawn update_str(heap_data, 8, 12); // no race mult_double(heap_data); cilk_sync; assert(__cilksan_error_count() == 0); break; case 17: cilk_spawn update_str(heap_data, 4, 12); // no race read_i(heap_data); cilk_sync; assert(__cilksan_error_count() == 0); break; case 18: cilk_spawn update_str(heap_data, 3, 5); // no race update_str(heap_data, 5, 8); cilk_sync; assert(__cilksan_error_count() == 0); break; case 19: read_and_write(&global_data); // read write race, but just 1 read_and_write(heap_data); cilk_sync; assert(__cilksan_error_count() == 1); break; } cilk_sync; free(heap_data); return 0; }
void read_and_write(data_t *data) { cilk_spawn read_double(data); increment_i(data); cilk_sync; }