コード例 #1
0
ファイル: nsssrv_mmap_cache.c プロジェクト: hujon/sssd
static void sss_mc_free_slots(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec)
{
    uint32_t slot;
    uint32_t num;
    uint32_t i;

    slot = MC_PTR_TO_SLOT(mcc->data_table, rec);
    num = MC_SIZE_TO_SLOTS(rec->len);
    for (i = 0; i < num; i++) {
        MC_CLEAR_BIT(mcc->free_table, slot + i);
    }
}
コード例 #2
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
static struct sss_mc_rec *sss_mc_get_record(struct sss_mc_ctx *mcc,
                                            size_t rec_len,
                                            struct sized_string *key)
{
    struct sss_mc_rec *old_rec = NULL;
    struct sss_mc_rec *rec;
    int old_slots;
    int num_slots;
    uint32_t base_slot;
    int i;

    num_slots = MC_SIZE_TO_SLOTS(rec_len);

    old_rec = sss_mc_find_record(mcc, key);
    if (old_rec) {
        old_slots = MC_SIZE_TO_SLOTS(old_rec->len);

        if (old_slots == num_slots) {
            return old_rec;
        }

        /* slot size changed, invalidate record and fall through to get a
        * fully new record */
        base_slot = MC_PTR_TO_SLOT(mcc->data_table, old_rec);
        sss_mc_invalidate_rec(mcc, old_rec);

        /* and now free slots */
        for (i = 0; i < old_slots; i++) {
            MC_CLEAR_BIT(mcc->free_table, base_slot + i);
        }
    }

    /* we are going to use more space, find enough free slots */
    base_slot = sss_mc_find_free_slots(mcc, num_slots);

    rec = MC_SLOT_TO_PTR(mcc->data_table, base_slot, struct sss_mc_rec);

    /* mark as not valid yet */
    MC_RAISE_INVALID_BARRIER(rec);
    rec->len = rec_len;
    rec->next = MC_INVALID_VAL;
    MC_LOWER_BARRIER(rec);

    /* and now mark slots as used */
    for (i = 0; i < num_slots; i++) {
        MC_SET_BIT(mcc->free_table, base_slot + i);
    }

    return rec;
}
コード例 #3
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
/* FIXME: This is a very simplistic, inefficient, memory allocator,
 * it will just free the oldest entries regardless of expiration if it
 * cycled the whole freebits map and found no empty slot */
static int sss_mc_find_free_slots(struct sss_mc_ctx *mcc, int num_slots)
{
    struct sss_mc_rec *rec;
    uint32_t tot_slots;
    uint32_t cur;
    uint32_t i;
    uint32_t t;
    bool used;

    tot_slots = mcc->ft_size * 8;

    /* Try to find a free slot w/o removing a nything first */
    /* FIXME: is it really worth it ? May be it is easier to
     * just recycle the next set of slots ? */
    if ((mcc->next_slot + num_slots) > tot_slots) {
        cur = 0;
    } else {
        cur = mcc->next_slot;
    }

    /* search for enough (num_slots) consecutive zero bits, indicating
     * consecutive empty slots */
    for (i = 0; i < mcc->ft_size; i++) {
        t = cur / 8;
        /* if all full in this byte skip directly to the next */
        if (mcc->free_table[t] == 0xff) {
            cur = ((cur + 8) & ~7);
            if (cur >= tot_slots) {
                cur = 0;
            }
            continue;
        }

        /* at least one bit in this byte is marked as empty */
        for (t = ((cur + 8) & ~7) ; cur < t; cur++) {
            MC_PROBE_BIT(mcc->free_table, cur, used);
            if (!used) break;
        }
        /* check if we have enough slots before hitting the table end */
        if ((cur + num_slots) > tot_slots) {
            cur = 0;
            continue;
        }

        /* check if we have at least num_slots empty starting from the first
         * we found in the previous steps */
        for (t = cur + num_slots; cur < t; cur++) {
            MC_PROBE_BIT(mcc->free_table, cur, used);
            if (used) break;
        }
        if (cur == t) {
            /* ok found num_slots consecutive free bits */
            return cur - num_slots;
        }
    }

    /* no free slots found, free occupied slots after next_slot */
    if ((mcc->next_slot + num_slots) > tot_slots) {
        cur = 0;
    } else {
        cur = mcc->next_slot;
    }
    for (i = 0; i < num_slots; i++) {
        MC_PROBE_BIT(mcc->free_table, cur + i, used);
        if (!used) continue;

        rec = MC_SLOT_TO_PTR(mcc->data_table, cur + i, struct sss_mc_rec);
        for (t = i + MC_SIZE_TO_SLOTS(rec->len); i < t; i++) {
            MC_CLEAR_BIT(mcc->free_table, cur + i);
        }
        sss_mc_invalidate_rec(mcc, rec);
    }

    mcc->next_slot = cur + num_slots;
    return cur;
}