Esempio n. 1
0
void mutex_lock(struct mutex *mutex)
{
    assert(mutex->name);
    SLOG(LOG_DEBUG, "Locking %s", mutex_name(mutex));
    uint64_t const start = bench_event_start();
#   ifdef WITH_BENCH
    int err = pthread_mutex_trylock(&mutex->mutex);
    switch (err) {
        case 0:
            bench_event_fire(&mutex->lock_for_free);
            break;
        case EBUSY:
            err = pthread_mutex_lock(&mutex->mutex);
            break;
        default:
            // other errors (for lock and trylock) handled below
            break;
    }
#   else
    // This was found to be noticably faster (-1% cpu load)
    int err = pthread_mutex_lock(&mutex->mutex);
#   endif
    if (! err) {
        bench_event_stop(&mutex->acquiring_lock, start);
        SLOG(LOG_DEBUG, "Locked %s", mutex_name(mutex));
    } else {
        SLOG(LOG_ERR, "Cannot lock %s: %s", mutex_name(mutex), strerror(err));
        // so be it
    }
}
Esempio n. 2
0
void doomer_run(void)
{
    enter_mono_region();

    SLOG(LOG_DEBUG, "Deleting doomed objects...");
    unsigned nb_dels = 0, nb_rescued = 0;

    // Bench time spent scanning death_row
    uint64_t start = bench_event_start();

    // Rescue from death_row the objects which ref count is > 0,
    // and queue into kill_list the one no longer accessible (they can not even reach each others)
    struct refs to_kill;
    SLIST_INIT(&to_kill);
    struct ref *r;
    while (NULL != (r = SLIST_FIRST(&death_row))) {
        SLIST_REMOVE_HEAD(&death_row, entry);
        if (r->count == 0) {
            SLIST_INSERT_HEAD(&to_kill, r, entry);
            nb_dels ++;
        } else {
            nb_rescued ++;
        }
    }

    SLOG(nb_dels + nb_rescued > 0 ? LOG_INFO:LOG_DEBUG, "Deleted %u objects, rescued %u", nb_dels, nb_rescued);

    bench_event_stop(&dooming, start);

    // No need to block parsing any more since the selected objects are not accessible
    leave_protected_region();

    // Delete all selected objects
    while (NULL != (r = SLIST_FIRST(&to_kill))) {
        // Beware that r->del() may doom further objects, which will be added in the death_row for next run
        SLOG(LOG_DEBUG, "Delete next object on kill list: %p", r);
        SLIST_REMOVE_HEAD(&to_kill, entry);
        r->entry.sle_next = NULL;   // the deletor must not care about the ref (since the decision to del the object was already taken)
        r->del(r);
    }
}