Esempio n. 1
0
void *
idr_replace(struct idr *idr, void *ptr, int id)
{
	struct idr_layer *il;
	void *res;
	int layer;
	int idx;

	res = ERR_PTR(-EINVAL);
	id &= MAX_ID_MASK;
	mtx_lock(&idr->lock);
	il = idr->top;
	layer = idr->layers - 1;
	if (il == NULL || id > idr_max(idr))
		goto out;
	while (layer && il) {
		il = il->ary[idr_pos(id, layer)];
		layer--;
	}
	idx = id & IDR_MASK;
	/*
	 * Replace still returns an error if the item was not allocated.
	 */
	if (il != NULL && (il->bitmap & (1 << idx)) != 0) {
		res = il->ary[idx];
		il->ary[idx] = ptr;
	}
out:
	mtx_unlock(&idr->lock);
	return (res);
}
Esempio n. 2
0
static void
idr_remove_locked(struct idr *idr, int id)
{
    struct idr_layer *il;
    int layer;
    int idx;

    id &= MAX_ID_MASK;
    il = idr->top;
    layer = idr->layers - 1;
    if (il == NULL || id > idr_max(idr))
        return;
    /*
     * Walk down the tree to this item setting bitmaps along the way
     * as we know at least one item will be free along this path.
     */
    while (layer && il) {
        idx = idr_pos(id, layer);
        il->bitmap |= 1 << idx;
        il = il->ary[idx];
        layer--;
    }
    idx = id & IDR_MASK;
    /*
     * At this point we've set free space bitmaps up the whole tree.
     * We could make this non-fatal and unwind but linux dumps a stack
     * and a warning so I don't think it's necessary.
     */
    if (il == NULL || (il->bitmap & (1 << idx)) != 0)
        panic("idr_remove: Item %d not allocated (%p, %p)\n",
              id, idr, il);
    il->ary[idx] = NULL;
    il->bitmap |= 1 << idx;
}
Esempio n. 3
0
void *
idr_get_next(struct idr *idr, int *nextidp)
{
    void *res = NULL;
    int id = *nextidp;

    mtx_lock(&idr->lock);
    for (; id <= idr_max(idr); id++) {
        res = idr_find_locked(idr, id);
        if (res == NULL)
            continue;
        *nextidp = id;
        break;
    }
    mtx_unlock(&idr->lock);
    return (res);
}
Esempio n. 4
0
static inline struct idr_layer *
idr_find_layer_locked(struct idr *idr, int id)
{
    struct idr_layer *il;
    int layer;

    id &= MAX_ID_MASK;
    il = idr->top;
    layer = idr->layers - 1;
    if (il == NULL || id > idr_max(idr))
        return (NULL);
    while (layer && il) {
        il = il->ary[idr_pos(id, layer)];
        layer--;
    }
    return (il);
}
Esempio n. 5
0
static inline void *
idr_find_locked(struct idr *idr, int id)
{
	struct idr_layer *il;
	void *res;
	int layer;

	mtx_assert(&idr->lock, MA_OWNED);

	id &= MAX_ID_MASK;
	res = NULL;
	il = idr->top;
	layer = idr->layers - 1;
	if (il == NULL || id > idr_max(idr))
		return (NULL);
	while (layer && il) {
		il = il->ary[idr_pos(id, layer)];
		layer--;
	}
	if (il != NULL)
		res = il->ary[id & IDR_MASK];
	return (res);
}
Esempio n. 6
0
void *
idr_find(struct idr *idr, int id)
{
    struct idr_layer *il;
    void *res;
    int layer;

    res = NULL;
    id &= MAX_ID_MASK;
    mtx_lock(&idr->lock);
    il = idr->top;
    layer = idr->layers - 1;
    if (il == NULL || id > idr_max(idr))
        goto out;
    while (layer && il) {
        il = il->ary[idr_pos(id, layer)];
        layer--;
    }
    if (il != NULL)
        res = il->ary[id & IDR_MASK];
out:
    mtx_unlock(&idr->lock);
    return (res);
}