diff options
| -rw-r--r-- | arch/tile/lib/spinlock_32.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index 485e24d62c6b..5cd1c4004eca 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c | |||
| @@ -167,23 +167,30 @@ void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val) | |||
| 167 | * when we compare them. | 167 | * when we compare them. |
| 168 | */ | 168 | */ |
| 169 | u32 my_ticket_; | 169 | u32 my_ticket_; |
| 170 | u32 iterations = 0; | ||
| 170 | 171 | ||
| 171 | /* Take out the next ticket; this will also stop would-be readers. */ | 172 | /* |
| 172 | if (val & 1) | 173 | * Wait until there are no readers, then bump up the next |
| 173 | val = get_rwlock(rwlock); | 174 | * field and capture the ticket value. |
| 174 | rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); | 175 | */ |
| 176 | for (;;) { | ||
| 177 | if (!(val & 1)) { | ||
| 178 | if ((val >> RD_COUNT_SHIFT) == 0) | ||
| 179 | break; | ||
| 180 | rwlock->lock = val; | ||
| 181 | } | ||
| 182 | delay_backoff(iterations++); | ||
| 183 | val = __insn_tns((int *)&rwlock->lock); | ||
| 184 | } | ||
| 175 | 185 | ||
| 176 | /* Extract my ticket value from the original word. */ | 186 | /* Take out the next ticket and extract my ticket value. */ |
| 187 | rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); | ||
| 177 | my_ticket_ = val >> WR_NEXT_SHIFT; | 188 | my_ticket_ = val >> WR_NEXT_SHIFT; |
| 178 | 189 | ||
| 179 | /* | 190 | /* Wait until the "current" field matches our ticket. */ |
| 180 | * Wait until the "current" field matches our ticket, and | ||
| 181 | * there are no remaining readers. | ||
| 182 | */ | ||
| 183 | for (;;) { | 191 | for (;;) { |
| 184 | u32 curr_ = val >> WR_CURR_SHIFT; | 192 | u32 curr_ = val >> WR_CURR_SHIFT; |
| 185 | u32 readers = val >> RD_COUNT_SHIFT; | 193 | u32 delta = ((my_ticket_ - curr_) & WR_MASK); |
| 186 | u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers; | ||
| 187 | if (likely(delta == 0)) | 194 | if (likely(delta == 0)) |
| 188 | break; | 195 | break; |
| 189 | 196 | ||
