| 332 | } |
| 333 | |
| 334 | epoch_t |
| 335 | epoch_alloc(const char *name, int flags) |
| 336 | { |
| 337 | epoch_t epoch; |
| 338 | int i; |
| 339 | |
| 340 | MPASS(name != NULL); |
| 341 | |
| 342 | if (__predict_false(!inited)) |
| 343 | panic("%s called too early in boot", __func__); |
| 344 | |
| 345 | EPOCH_LOCK(); |
| 346 | |
| 347 | /* |
| 348 | * Find a free index in the epoch array. If no free index is |
| 349 | * found, try to use the index after the last one. |
| 350 | */ |
| 351 | for (i = 0;; i++) { |
| 352 | /* |
| 353 | * If too many epochs are currently allocated, |
| 354 | * return NULL. |
| 355 | */ |
| 356 | if (i == MAX_EPOCHS) { |
| 357 | epoch = NULL; |
| 358 | goto done; |
| 359 | } |
| 360 | if (epoch_array[i].e_in_use == 0) |
| 361 | break; |
| 362 | } |
| 363 | |
| 364 | epoch = epoch_array + i; |
| 365 | ck_epoch_init(&epoch->e_epoch); |
| 366 | epoch_ctor(epoch); |
| 367 | epoch->e_flags = flags; |
| 368 | epoch->e_name = name; |
| 369 | sx_init(&epoch->e_drain_sx, "epoch-drain-sx"); |
| 370 | mtx_init(&epoch->e_drain_mtx, "epoch-drain-mtx", NULL, MTX_DEF); |
| 371 | |
| 372 | /* |
| 373 | * Set e_in_use last, because when this field is set the |
| 374 | * epoch_call_task() function will start scanning this epoch |
| 375 | * structure. |
| 376 | */ |
| 377 | atomic_store_rel_int(&epoch->e_in_use, 1); |
| 378 | done: |
| 379 | EPOCH_UNLOCK(); |
| 380 | return (epoch); |
| 381 | } |
| 382 | |
| 383 | void |
| 384 | epoch_free(epoch_t epoch) |
no test coverage detected