Exemple #1
0
static int put(struct store *st, const void *buf, size_t len, struct addr *at)
{
    struct fstore *fst;
    struct addr pa;
    idx_t i, pi;
    struct idxent ie;
    loff_t leoff;
    int c;
    struct logent le;
    
    if(len > STORE_MAXBLSZ) {
	errno = E2BIG;
	return(-1);
    }

    fst = st->pdata;
    hash(buf, len, &pa);
    if(at != NULL)
	memcpy(at->hash, pa.hash, 32);
    
    if(lookup(fst, &pa, &pi) != -1)
	return(0);
    
    memcpy(le.magic, LOGENTMAGIC, 4);
    le.name = pa;
    le.len = len;
    le.fl = 0;
    /* XXX: Thread safety { */
    leoff = fst->logsize;
    fst->logsize += sizeof(le) + len;
    /* } */
    /* XXX: Handle data with embedded LOGENTMAGIC */
    writeall(fst->logfd, &le, sizeof(le), leoff);
    writeall(fst->logfd, buf, len, leoff + sizeof(le));

    i = newindex(fst);
    assert(!getidx(fst, i, &ie));
    ie.addr = pa;
    ie.off = leoff;
    assert(!putidx(fst, i, &ie));
    if(pi != -1) {
	assert(!getidx(fst, pi, &ie));
	c = addrcmp(&pa, &ie.addr);
	if(c < 0)
	    ie.l = i;
	else
	    ie.r = i;
	assert(!putidx(fst, pi, &ie));
    }
    
    return(0);
}
Exemple #2
0
static void
rumpsp_close(struct rumpsp_chan *chan)
{
	int fd = chan->fd;
	unsigned int idx = getidx(chan);
	struct pollfd *pfd = &pollfds[idx];
	
	chan->token = NULL;
	chan->fd = -1;
	
	pfd->fd = -1;
	pfd->events = 0;
	
	if (idx == maxidx) {
		idx = maxidx - 1;
		while (idx) {
			if (chanfds[idx].fd != -1) {
				maxidx = idx;
				break;
			}
			idx--;
		}
	}

	close(fd);
}
Exemple #3
0
static idx_t lookup(struct fstore *fst, struct addr *a, idx_t *parent)
{
    idx_t i;
    struct idxent ie;
    int c;
    
    if(fst->idxsize == 0) {
	if(parent != NULL)
	    *parent = -1;
	return(-1);
    }
    i = 0;
    while(1) {
	assert(!getidx(fst, i, &ie));
	c = addrcmp(a, &ie.addr);
	if(c < 0) {
	    if(ie.l == 0) {
		if(parent != NULL)
		    *parent = i;
		return(-1);
	    }
	    i = ie.l;
	} else if(c > 0) {
	    if(ie.r == 0) {
		if(parent != NULL)
		    *parent = i;
		return(-1);
	    }
	    i = ie.r;
	} else {
	    return(i);
	}
    }
}
Exemple #4
0
int main(void)
{
	int array[5];
	int idx = getidx();
	// getidx() returns 2, but slicer
	// does not know it, so array[idx] is
	// pointer with unknown offset to array
	array[idx] = 7;

	assert(array[2] == 7);
	return 0;
}
Exemple #5
0
int main(void)
{
	int array[5];
	int idx = getidx();

	// some pointer arithmetic
	int *p = array;
	p += idx;
	++p;

	*p = 7;

	assert(array[3] == 7);
	return 0;
}
Exemple #6
0
static ssize_t get(struct store *st, void *buf, size_t len, struct addr *at)
{
    idx_t i;
    struct idxent ie;
    struct fstore *fst;
    struct logent le;
    struct addr v;
    char tmpbuf[STORE_MAXBLSZ];
    
    fst = st->pdata;
    if((i = lookup(fst, at, NULL)) == -1) {
	errno = ENOENT;
	return(-1);
    }
    assert(!getidx(fst, i, &ie));
    
    if(readall(fst->logfd, &le, sizeof(le), ie.off)) {
	flog(LOG_CRIT, "could not read log entry: %s", strerror(errno));
	errno = EIO;
	return(-1);
    }
    if(memcmp(le.magic, LOGENTMAGIC, 4)) {
	flog(LOG_CRIT, "invalid magic in log");
	errno = EIO;
	return(-1);
    }
    if(addrcmp(&le.name, at)) {
	flog(LOG_CRIT, "did not receive correct block from log");
	errno = EIO;
	return(-1);
    }
    if(readall(fst->logfd, tmpbuf, le.len, ie.off + sizeof(le))) {
	flog(LOG_CRIT, "could not read log data: %s", strerror(errno));
	errno = EIO;
	return(-1);
    }
    hash(tmpbuf, le.len, &v);
    if(addrcmp(&v, &le.name)) {
	flog(LOG_CRIT, "log data did not verify against hash");
	errno = EIO;
	return(-1);
    }
    if(buf != NULL)
	memcpy(buf, tmpbuf, min(len, le.len));
    return(le.len);
}
Exemple #7
0
static int 
rumpsp_disable_events(struct rumpsp_chan *chan, int events)
{
	struct pollfd *pfd = &pollfds[getidx(chan)];

	if (events & RUMPSP_EVENT_WRITABLE) {
		pfd->events &= ~POLLOUT;
	}
	
	if (events & RUMPSP_EVENT_READABLE) {
		pfd->events &= ~POLLIN;
	}
	
	if (!pfd->events)
		pfd->fd= -1;
	
	return 0;
}
Exemple #8
0
appkey_t 
__appkey_getbyname(char *app, char *key)
{
    struct appkey *ak;

    if (NULL==app) {
        return os_assert_value(INVALID_APPKEY);
    }
    else if (NULL==key) {
        return os_assert_value(INVALID_APPKEY);
    }

    ak = getbyname(app, key);
    if (NULL==ak) {
        return INVALID_APPKEY;
    }
    
    return ak_make(getidx(ak), getoffset(ak));
}
Exemple #9
0
/**
 * Get a suitable buffer in the cache to read a page and set db->pagbuf
 * accordingly.
 *
 * The '`loaded'' parameter, if non-NULL, is set to TRUE if page was already
 * held in the cache, FALSE when it needs to be loaded.
 *
 * @return TRUE if OK, FALSE if we could not allocate a suitable buffer, leaving
 * the old db->pagbuf intact.
 */
gboolean
readbuf(DBM *db, long num, gboolean *loaded)
{
	struct lru_cache *cache = db->cache;
	void *value;
	long idx;
	gboolean good_page;

	g_assert(num >= 0);

	if (
		g_hash_table_lookup_extended(cache->pagnum,
			ulong_to_pointer(num), NULL, &value)
	) {
		hash_list_moveto_head(cache->used, value);
		idx = pointer_to_int(value);

		g_assert(idx >= 0 && idx < cache->pages);
		g_assert(cache->numpag[idx] == num);

		good_page = TRUE;
		cache->rhits++;
	} else {
		idx = getidx(db, num);
		if (-1 == idx)
			return FALSE;	/* Do not update db->pagbuf */

		good_page = FALSE;
		cache->rmisses++;
	}

	db->pagbuf = cache->arena + OFF_PAG(idx);
	if (loaded != NULL)
		*loaded = good_page;

	return TRUE;
}
Exemple #10
0
void dTensor4d::set(int n1,int n2,int n3,int n4,double value)
{
    int k = getidx(n1,n2,n3,n4);
    bounds_check();
    vec[k] = value;
}
Exemple #11
0
/*
  locks are automatically released on program exit,
  so don't bother with unlocking on exceptions
 */
int main(int argc, char *argv[]) {
    const  char   *mhdir;
    struct dirent *de = NULL;
    DIR           *dir;
    int           dfd, i, spret;
    num_t         maxidx = 0, curidx;
    char          numname[NUM_LEN+1];

    if (argc < 3) {
        fprintf(stderr, "%s <mh dir> <message on same fs> ...\n", argv[0]);
        return 1;
    }

    mhdir = argv[1];

    /* init logging */
    syslog_init();

    /* signals */
    set_signals();

    /* open directory */
    if ((dir = opendir(mhdir)) == NULL)
        error();

    /* get corresponding file descriptor for lock / access */
    if ((dfd = dirfd(dir)) == -1)
        error();

    /* lock directory with timeout */
    alarm(LOCK_TMOUT);
    if (flock(dfd, LOCK_EX) == -1) {
        if (errno == EINTR  &&  alrm)
            flogexit(LOG_ERR, "timed out while locking %s", mhdir);
        else
            error();
    }
    alarm(0);

    /* find max entry, don't bother with file types */
    for (errno = 0;  (de = readdir(dir)) != NULL; )
        if ((curidx = getidx(de->d_name)) != NOT_NUM  &&  curidx > maxidx)
            maxidx = curidx;

    if (de == NULL  &&  errno)
        error();

    
    /* deliver messages */
    for (i = 2, ++maxidx;  i < argc;  ++i, ++maxidx) {
        if (maxidx == NOT_NUM  ||  maxidx == 0)
            flogexit(LOG_ERR, "indexes exhausted, %llu not legal", maxidx);

        /* convert to string, but also check back due to possible locale-related problems */
        spret = snprintf(numname, sizeof(numname), "%llu", maxidx);
        if (spret < 0  ||  spret >= sizeof(numname)  ||  getidx(numname) != maxidx)
            flogexit(LOG_ERR, "could not convert %llu to file name", maxidx);

        /* rename() may replace an externally created file, so use link/unlink */
        if (linkat(AT_FDCWD, argv[i], dfd, numname, 0) == -1)
            error();
        if (unlink(argv[i]) == -1)
            error();

        flog(LOG_INFO, "delivered %s/%s", mhdir, numname);
    }


    /* unlock (explicitly) */
    if (flock(dfd, LOCK_UN) == -1)
        error();

    /* close directory */
    if (closedir(dir) == -1)
        error();

    closelog();
    return 0;
}
Exemple #12
0
 bool is_first(const vaptr_t *vp) const { return getidx(vp) == 0; }
Exemple #13
0
/**
 * Cache new page held in memory if there are deferred writes configured.
 * @return TRUE on success.
 */
gboolean
cachepag(DBM *db, char *pag, long num)
{
	struct lru_cache *cache = db->cache;
	void *value;

	g_assert(num >= 0);

	/*
	 * Coming from makroom() where we allocated a new page, starting at "pag".
	 *
	 * Normally the page should not be cached, but it is possible we iterated
	 * over the hash table and traversed the page on disk as a hole, and cached
	 * it during the process.  If present, it must be clean and should hold
	 * no data (or the bitmap forest in the .dir file is corrupted).
	 *
	 * Otherwise, we cache the new page and hold it there if we we can defer
	 * writes, or flush it to disk immediately (without caching it).
	 */

	if (
		g_hash_table_lookup_extended(cache->pagnum,
			ulong_to_pointer(num), NULL, &value)
	) {
		long idx;
		unsigned short *ino;
		unsigned weird = 0;
		char *cpag;

		/*
		 * Do not move the page to the head of the cache list.
		 *
		 * This page should not have been cached (it was supposed to be a
		 * hole up to now) and its being cached now does not constitute usage.
		 */

		idx = pointer_to_int(value);
		g_assert(idx >= 0 && idx < cache->pages);
		g_assert(cache->numpag[idx] == num);

		/*
		 * Not a read hit since we're about to supersede the data
		 */

		cpag = cache->arena + OFF_PAG(idx);
		ino = (unsigned short *) cpag;

		if (ino[0] != 0) {
			weird++;
			g_warning("sdbm: \"%s\": new page #%ld was cached but not empty",
				db->name, num);
		}
		if (cache->dirty[idx]) {
			weird++;
			g_warning("sdbm: \"%s\": new page #%ld was cached and not clean",
				db->name, num);
		}
		if (weird > 0) {
			g_warning("sdbm: \"%s\": previous warning%s indicate possible "
				"corruption in the bitmap forest",
				db->name, 1 == weird ? "" : "s");
		}

		/*
		 * Supersede cached page with new page created by makroom().
		 */

		memmove(cpag, pag, DBM_PBLKSIZ);

		if (cache->write_deferred) {
			cache->dirty[idx] = TRUE;
		} else {
			cache->dirty[idx] = !flushpag(db, pag, num);
		}
		return TRUE;
	} else if (cache->write_deferred) {
		long idx;
		char *cpag;

		idx = getidx(db, num);
		if (-1 == idx)
			return FALSE;

		cpag = cache->arena + OFF_PAG(idx);
		memmove(cpag, pag, DBM_PBLKSIZ);
		cache->dirty[idx] = TRUE;
		return TRUE;
	} else {
		return flushpag(db, pag, num);
	}
}
Exemple #14
0
void dTensor2d::set(int n1,int n2,double value)
{
    int k = getidx(n1,n2);
    bounds_check();
    vec[k] = value;
}
Exemple #15
0
double& dTensor2d::fetch(int n1,int n2)
{
    int k = getidx(n1,n2);
    bounds_check();
    return vec[k];
}
Exemple #16
0
const double& dTensor2d::get(int n1,int n2) const
{
    int k = getidx(n1,n2);
    bounds_check();
    return vec[k];
}
Exemple #17
0
const double& dTensor4d::get(int n1,int n2,int n3,int n4) const
{
    int k = getidx(n1,n2,n3,n4);
    bounds_check();
    return vec[k];
}
Exemple #18
0
double& dTensor4d::fetch(int n1,int n2,int n3,int n4)
{
    int k = getidx(n1,n2,n3,n4);
    bounds_check();
    return vec[k];
}