* Push the timehands update to the shared page. * * The lockless update scheme is similar to the one used to update the * in-kernel timehands, see sys/kern/kern_tc.c:tc_windup() (which * calls us after the timehands are updated). */
| 143 | * calls us after the timehands are updated). |
| 144 | */ |
| 145 | static void |
| 146 | timehands_update(struct vdso_sv_tk *svtk) |
| 147 | { |
| 148 | struct vdso_timehands th; |
| 149 | struct vdso_timekeep *tk; |
| 150 | uint32_t enabled, idx; |
| 151 | |
| 152 | enabled = tc_fill_vdso_timehands(&th); |
| 153 | th.th_gen = 0; |
| 154 | idx = svtk->sv_timekeep_curr; |
| 155 | if (++idx >= VDSO_TH_NUM) |
| 156 | idx = 0; |
| 157 | svtk->sv_timekeep_curr = idx; |
| 158 | if (++svtk->sv_timekeep_gen == 0) |
| 159 | svtk->sv_timekeep_gen = 1; |
| 160 | |
| 161 | tk = (struct vdso_timekeep *)(shared_page_mapping + |
| 162 | svtk->sv_timekeep_off); |
| 163 | tk->tk_th[idx].th_gen = 0; |
| 164 | atomic_thread_fence_rel(); |
| 165 | if (enabled) |
| 166 | tk->tk_th[idx] = th; |
| 167 | atomic_store_rel_32(&tk->tk_th[idx].th_gen, svtk->sv_timekeep_gen); |
| 168 | atomic_store_rel_32(&tk->tk_current, idx); |
| 169 | |
| 170 | /* |
| 171 | * The ordering of the assignment to tk_enabled relative to |
| 172 | * the update of the vdso_timehands is not important. |
| 173 | */ |
| 174 | tk->tk_enabled = enabled; |
| 175 | } |
| 176 | |
| 177 | #ifdef COMPAT_FREEBSD32 |
| 178 | static void |
no test coverage detected