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); }
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); }
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); } } }
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; }
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; }
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); }
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; }
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)); }
/** * 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; }
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; }
/* 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; }
bool is_first(const vaptr_t *vp) const { return getidx(vp) == 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); } }
void dTensor2d::set(int n1,int n2,double value) { int k = getidx(n1,n2); bounds_check(); vec[k] = value; }
double& dTensor2d::fetch(int n1,int n2) { int k = getidx(n1,n2); bounds_check(); return vec[k]; }
const double& dTensor2d::get(int n1,int n2) const { int k = getidx(n1,n2); bounds_check(); return vec[k]; }
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]; }
double& dTensor4d::fetch(int n1,int n2,int n3,int n4) { int k = getidx(n1,n2,n3,n4); bounds_check(); return vec[k]; }