* Enter a read section. */
| 105 | * Enter a read section. |
| 106 | */ |
| 107 | static inline void |
| 108 | smr_enter(smr_t smr) |
| 109 | { |
| 110 | |
| 111 | critical_enter(); |
| 112 | smr = zpcpu_get(smr); |
| 113 | KASSERT((smr->c_flags & SMR_LAZY) == 0, |
| 114 | ("smr_enter(%s) lazy smr.", smr->c_shared->s_name)); |
| 115 | KASSERT(smr->c_seq == 0, |
| 116 | ("smr_enter(%s) does not support recursion.", |
| 117 | smr->c_shared->s_name)); |
| 118 | |
| 119 | /* |
| 120 | * Store the current observed write sequence number in our |
| 121 | * per-cpu state so that it can be queried via smr_poll(). |
| 122 | * Frees that are newer than this stored value will be |
| 123 | * deferred until we call smr_exit(). |
| 124 | * |
| 125 | * An acquire barrier is used to synchronize with smr_exit() |
| 126 | * and smr_poll(). |
| 127 | * |
| 128 | * It is possible that a long delay between loading the wr_seq |
| 129 | * and storing the c_seq could create a situation where the |
| 130 | * rd_seq advances beyond our stored c_seq. In this situation |
| 131 | * only the observed wr_seq is stale, the fence still orders |
| 132 | * the load. See smr_poll() for details on how this condition |
| 133 | * is detected and handled there. |
| 134 | */ |
| 135 | /* This is an add because we do not have atomic_store_acq_int */ |
| 136 | atomic_add_acq_int(&smr->c_seq, smr_shared_current(smr->c_shared)); |
| 137 | } |
| 138 | |
| 139 | /* |
| 140 | * Exit a read section. |
no test coverage detected