X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=formal-model%2Furcu-controldataflow%2Furcu.spin;h=44bbe523e153abfe52c39ee3eac957a4b7f22f46;hb=794a737edb08278087a6628a37235d19ff68fce1;hp=6ec1655654367c75e78ca547dcbaf07fe4af73ca;hpb=f089ec2496f9d72eb737de6ac4786b81f5d55a7e;p=urcu.git diff --git a/formal-model/urcu-controldataflow/urcu.spin b/formal-model/urcu-controldataflow/urcu.spin index 6ec1655..44bbe52 100644 --- a/formal-model/urcu-controldataflow/urcu.spin +++ b/formal-model/urcu-controldataflow/urcu.spin @@ -243,7 +243,6 @@ inline smp_mb(i, j) } } - #ifdef REMOTE_BARRIERS bit reader_barrier[NR_READERS]; @@ -269,32 +268,53 @@ inline smp_mb_recv(i, j) :: (reader_barrier[get_readerid()] == 1) -> smp_mb(i, j); reader_barrier[get_readerid()] = 0; - :: 1 -> skip; + :: 1 -> + /* + * Busy-looping waiting for other barrier requests are not considered as + * non-progress. + */ +#ifdef READER_PROGRESS +progress_reader2: +#endif + skip; :: 1 -> break; od; } -inline smp_mb_send(i, j) -{ - smp_mb(i, j); - i = 0; - do - :: i < NR_READERS -> - reader_barrier[i] = 1; - do - :: (reader_barrier[i] == 1) -> skip; - :: (reader_barrier[i] == 0) -> break; - od; - i++; - :: i >= NR_READERS -> - break - od; - smp_mb(i, j); +#ifdef WRITER_PROGRESS +#define PROGRESS_LABEL(progressid) progress_writer_progid_##progressid: +#else +#define PROGRESS_LABEL(progressid) +#endif + +#define smp_mb_send(i, j, progressid) \ +{ \ + smp_mb(i, j); \ + i = 0; \ + do \ + :: i < NR_READERS -> \ + reader_barrier[i] = 1; \ + do \ + :: (reader_barrier[i] == 1) -> \ + /* \ + * Busy-looping waiting for reader barrier handling is of little\ + * interest, given the reader has the ability to totally ignore \ + * barrier requests. \ + */ \ +PROGRESS_LABEL(progressid) \ + skip; \ + :: (reader_barrier[i] == 0) -> break; \ + od; \ + i++; \ + :: i >= NR_READERS -> \ + break \ + od; \ + smp_mb(i, j); \ } #else -#define smp_mb_send smp_mb +#define smp_mb_send(i, j, progressid) smp_mb(i, j) #define smp_mb_reader smp_mb #define smp_mb_recv(i, j) @@ -887,6 +907,8 @@ progress_writer1: PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP); PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP); PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT); + /* For single flip, we need to know the current parity */ + cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT; #endif do :: 1 -> @@ -919,7 +941,12 @@ smp_mb_send1_end: ooo_mem(i); /* ONLY WAITING FOR READER 0 */ tmp2 = READ_CACHED_VAR(urcu_active_readers[0]); - cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT; +#ifndef SINGLE_FLIP + /* In normal execution, we are always starting by + * waiting for the even parity. + */ + cur_gp_val = RCU_GP_CTR_BIT; +#endif if :: (tmp2 & RCU_GP_CTR_NEST_MASK) && ((tmp2 ^ cur_gp_val) & RCU_GP_CTR_BIT) -> @@ -973,10 +1000,9 @@ smp_mb_send2_end: ooo_mem(i); /* ONLY WAITING FOR READER 0 */ tmp2 = READ_CACHED_VAR(urcu_active_readers[0]); - cur_gp_val = cur_gp_val ^ RCU_GP_CTR_BIT; if :: (tmp2 & RCU_GP_CTR_NEST_MASK) - && ((tmp2 ^ cur_gp_val) & RCU_GP_CTR_BIT) -> + && ((tmp2 ^ 0) & RCU_GP_CTR_BIT) -> PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP); :: else -> PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT); @@ -1046,18 +1072,18 @@ progress_writer2: /* Non-atomic parts of the loop */ goto end; smp_mb_send1: - smp_mb_send(i, j); + smp_mb_send(i, j, 1); goto smp_mb_send1_end; #ifndef GEN_ERROR_WRITER_PROGRESS smp_mb_send2: - smp_mb_send(i, j); + smp_mb_send(i, j, 2); goto smp_mb_send2_end; smp_mb_send3: - smp_mb_send(i, j); + smp_mb_send(i, j, 3); goto smp_mb_send3_end; #endif smp_mb_send4: - smp_mb_send(i, j); + smp_mb_send(i, j, 4); goto smp_mb_send4_end; end: skip;