Пример #1
0
static void primop_table_ref(long argc) {
    object o = sp[1];
    long i = the_long(2,o);
    o = *sp++;
    TYPE_CHECK(TABLE_P(o),1,"table",o);
    if (i < 0 || i >= TABLE_COUNT(o))
        error(MAKE_FIXNUM(i),"index out of range");
    *sp = TABLE_ELEMENTS(o)[i*2+1];
}
Пример #2
0
object make_table(long capacity) {
  object bindings = make_vector(capacity*2, false_object);
  long size = sizeof(struct table_heap_structure);
  object *ve, v;
  PUSH_GC_PROTECT(bindings);
  v = make_heap_object(TABLE_TYPE,size);
  TABLE_COUNT(v) = 0;
  VECTOR_TAG(bindings) = false_object;
  /* FIX ME */
  TABLE_BINDINGS(v) = bindings;
  POP_GC_PROTECT(1);
  return v;
}
Пример #3
0
static void primop_table_get(long argc) {
    object tbl = *sp++;
    object key = *sp;
    object *pBindings;
    long i, imax;
    TYPE_CHECK(TABLE_P(tbl),1,"table",tbl);
    pBindings = TABLE_ELEMENTS(tbl);
    imax = TABLE_COUNT(tbl);
    while (imax-- > 0) {
      if (eq_p(*pBindings++, key)) {
	*sp = *pBindings;
	return;
      } else
	pBindings++;
    }
    *sp = false_object;
}
Пример #4
0
/*
 * Put a lnode in the table
 */
static void
lsave(lnode_t *lp, struct loinfo *li)
{
    ASSERT(lp->lo_vp);
    ASSERT(MUTEX_HELD(TABLE_LOCK(lp->lo_vp, li)));

#ifdef LODEBUG
    lo_dprint(4, "lsave lp %p hash %d\n",
              lp, ltablehash(lp->lo_vp, li));
#endif

    TABLE_COUNT(lp->lo_vp, li)++;
    lp->lo_next = TABLE_BUCKET(lp->lo_vp, li);
    TABLE_BUCKET(lp->lo_vp, li) = lp;

    if (li->li_refct > (li->li_htsize << lo_resize_threshold)) {
        TABLE_LOCK_EXIT(lp->lo_vp, li);
        lgrow(li, li->li_htsize << lo_resize_factor);
        TABLE_LOCK_ENTER(lp->lo_vp, li);
    }
}
Пример #5
0
static void primop_table_count(long argc) {
    object o = *sp;
    TYPE_CHECK(TABLE_P(o),1,"table",o);
    *sp = MAKE_FIXNUM(TABLE_COUNT(o));
}
Пример #6
0
/*
 * Remove a lnode from the table
 */
void
freelonode(lnode_t *lp)
{
    lnode_t *lt;
    lnode_t *ltprev = NULL;
    struct lfsnode *lfs, *nextlfs;
    struct vfs *vfsp;
    struct vnode *vp = ltov(lp);
    struct vnode *realvp = realvp(vp);
    struct loinfo *li = vtoli(vp->v_vfsp);

#ifdef LODEBUG
    lo_dprint(4, "freelonode lp %p hash %d\n",
              lp, ltablehash(lp->lo_vp, li));
#endif
    TABLE_LOCK_ENTER(lp->lo_vp, li);

    mutex_enter(&vp->v_lock);
    if (vp->v_count > 1) {
        vp->v_count--;	/* release our hold from vn_rele */
        mutex_exit(&vp->v_lock);
        TABLE_LOCK_EXIT(lp->lo_vp, li);
        return;
    }
    mutex_exit(&vp->v_lock);

    for (lt = TABLE_BUCKET(lp->lo_vp, li); lt != NULL;
            ltprev = lt, lt = lt->lo_next) {
        if (lt == lp) {
#ifdef LODEBUG
            lo_dprint(4, "freeing %p, vfsp %p\n",
                      vp, vp->v_vfsp);
#endif
            atomic_dec_32(&li->li_refct);
            vfsp = vp->v_vfsp;
            vn_invalid(vp);
            if (vfsp != li->li_mountvfs) {
                mutex_enter(&li->li_lfslock);
                /*
                 * Check for unused lfs
                 */
                lfs = li->li_lfs;
                while (lfs != NULL) {
                    nextlfs = lfs->lfs_next;
                    if (vfsp == &lfs->lfs_vfs) {
                        lfs_rele(lfs, li);
                        break;
                    }
                    if (lfs->lfs_vfs.vfs_count == 1) {
                        /*
                         * Lfs is idle
                         */
                        freelfsnode(lfs, li);
                    }
                    lfs = nextlfs;
                }
                mutex_exit(&li->li_lfslock);
            }
            if (ltprev == NULL) {
                TABLE_BUCKET(lt->lo_vp, li) = lt->lo_next;
            } else {
                ltprev->lo_next = lt->lo_next;
            }
            TABLE_COUNT(lt->lo_vp, li)--;
            TABLE_LOCK_EXIT(lt->lo_vp, li);
            kmem_cache_free(lnode_cache, lt);
            vn_free(vp);
            VN_RELE(realvp);
            return;
        }
    }
    panic("freelonode");
    /*NOTREACHED*/
}