| 403 | } |
| 404 | |
| 405 | int bthread_id_lock_and_reset_range_verbose( |
| 406 | bthread_id_t id, void **pdata, int range, const char *location) { |
| 407 | bthread::Id* const meta = address_resource(bthread::get_slot(id)); |
| 408 | if (!meta) { |
| 409 | return EINVAL; |
| 410 | } |
| 411 | const uint32_t id_ver = bthread::get_version(id); |
| 412 | uint32_t* butex = meta->butex; |
| 413 | bool ever_contended = false; |
| 414 | meta->mutex.lock(); |
| 415 | while (meta->has_version(id_ver)) { |
| 416 | if (*butex == meta->first_ver) { |
| 417 | // contended locker always wakes up the butex at unlock. |
| 418 | meta->lock_location = location; |
| 419 | if (range == 0) { |
| 420 | // fast path |
| 421 | } else if (range < 0 || |
| 422 | range > bthread::ID_MAX_RANGE || |
| 423 | range + meta->first_ver <= meta->locked_ver) { |
| 424 | LOG_IF(FATAL, range < 0) << "range must be positive, actually " |
| 425 | << range; |
| 426 | LOG_IF(FATAL, range > bthread::ID_MAX_RANGE) |
| 427 | << "max range is " << bthread::ID_MAX_RANGE |
| 428 | << ", actually " << range; |
| 429 | } else { |
| 430 | meta->locked_ver = meta->first_ver + range; |
| 431 | } |
| 432 | *butex = (ever_contended ? meta->contended_ver() : meta->locked_ver); |
| 433 | meta->mutex.unlock(); |
| 434 | if (pdata) { |
| 435 | *pdata = meta->data; |
| 436 | } |
| 437 | return 0; |
| 438 | } else if (*butex != meta->unlockable_ver()) { |
| 439 | *butex = meta->contended_ver(); |
| 440 | uint32_t expected_ver = *butex; |
| 441 | meta->mutex.unlock(); |
| 442 | ever_contended = true; |
| 443 | if (bthread::butex_wait(butex, expected_ver, NULL) < 0 && |
| 444 | errno != EWOULDBLOCK && errno != EINTR) { |
| 445 | return errno; |
| 446 | } |
| 447 | meta->mutex.lock(); |
| 448 | } else { // bthread_id_about_to_destroy was called. |
| 449 | meta->mutex.unlock(); |
| 450 | return EPERM; |
| 451 | } |
| 452 | } |
| 453 | meta->mutex.unlock(); |
| 454 | return EINVAL; |
| 455 | } |
| 456 | |
| 457 | int bthread_id_error_verbose(bthread_id_t id, int error_code, |
| 458 | const char *location) { |
no test coverage detected