| 178 | } |
| 179 | |
| 180 | void |
| 181 | tsd_state_set(tsd_t *tsd, uint8_t new_state) { |
| 182 | /* Only the tsd module can change the state *to* recompute. */ |
| 183 | assert(new_state != tsd_state_nominal_recompute); |
| 184 | uint8_t old_state = tsd_atomic_load(&tsd->state, ATOMIC_RELAXED); |
| 185 | if (old_state > tsd_state_nominal_max) { |
| 186 | /* |
| 187 | * Not currently in the nominal list, but it might need to be |
| 188 | * inserted there. |
| 189 | */ |
| 190 | assert(!tsd_in_nominal_list(tsd)); |
| 191 | tsd_atomic_store(&tsd->state, new_state, ATOMIC_RELAXED); |
| 192 | if (new_state <= tsd_state_nominal_max) { |
| 193 | tsd_add_nominal(tsd); |
| 194 | } |
| 195 | } else { |
| 196 | /* |
| 197 | * We're currently nominal. If the new state is non-nominal, |
| 198 | * great; we take ourselves off the list and just enter the new |
| 199 | * state. |
| 200 | */ |
| 201 | assert(tsd_in_nominal_list(tsd)); |
| 202 | if (new_state > tsd_state_nominal_max) { |
| 203 | tsd_remove_nominal(tsd); |
| 204 | tsd_atomic_store(&tsd->state, new_state, |
| 205 | ATOMIC_RELAXED); |
| 206 | } else { |
| 207 | /* |
| 208 | * This is the tricky case. We're transitioning from |
| 209 | * one nominal state to another. The caller can't know |
| 210 | * about any races that are occuring at the same time, |
| 211 | * so we always have to recompute no matter what. |
| 212 | */ |
| 213 | tsd_slow_update(tsd); |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | static bool |
| 219 | tsd_data_init(tsd_t *tsd) { |
no test coverage detected