8cc7dee111a52eed9f6e65a01e67730af13b43b4 braney Thu Jun 6 15:30:22 2019 -0700 ongoing work on trackDb caching in shared memory diff --git src/hg/lib/trackDbCustom.c src/hg/lib/trackDbCustom.c index 062dd64..e87db2d 100644 --- src/hg/lib/trackDbCustom.c +++ src/hg/lib/trackDbCustom.c @@ -1638,57 +1638,111 @@ for(tdb = list; tdb; tdb = tdb->next) { struct trackDb *newTdb = lmCloneTdb(lm, tdb, parent, superHash); if (prevTdb) prevTdb->next = newTdb; else newList = newTdb; prevTdb = newTdb; } return newList; } -struct trackDb *mapSharedMemTrackDb(char *file, unsigned long address, unsigned long size) -/* Use a hunk of shared memory as our trackDb list. */ +struct trackDb *trackDbCache(char *db) +/* Check to see if this db has a cached trackDb. */ { -int oflags=O_RDWR | O_CREAT; -int fd = shm_open(file, oflags, 0666 ); +char dirName[4096]; + +safef(dirName, sizeof dirName, "/dev/shm/trackDbCache/%s", db); +if (!isDirectory(dirName)) + return NULL; + +// look for files named by the address they use +struct slName *files = listDir(dirName, "*"); +for(; files; files = files->next) + { + char sharedMemoryName[4096]; + safef(sharedMemoryName, sizeof sharedMemoryName, "trackDbCache/%s/%s", db, files->name); + + int oflags = O_RDWR; + int fd = shm_open(sharedMemoryName, oflags, 0666 ); + if (fd < 0) + continue; + + unsigned long address = atoi(files->name); // the name of the file is the address it uses + char fileName[4096]; + safef(fileName, sizeof fileName, "/dev/shm/trackDbCache/%s/%s", db, files->name); + unsigned long size = fileSize(fileName); + u_char *mem = (u_char *) mmap((void *)address, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); -u_char *ret = mem + 32; // lm header is 32 bytes long + if ((unsigned long)mem == address) // make sure we can get this address + { + u_char *ret = mem + lmBlockHeaderSize(); return (struct trackDb *)ret; } + munmap((void *)address, size); + close(fd); + } -struct trackDb *cloneTdbListToSharedMem(struct trackDb *list, unsigned long size) +return NULL; +} + +void trackDbCloneTdbListToSharedMem(char *db, struct trackDb *list, unsigned long size) /* Allocate shared memory and clone trackDb list into it. */ { int oflags=O_RDWR | O_CREAT; // should use a unique name -char *file ="brtest/flart"; -int fd = shm_open(file, oflags, 0666 ); +char dirName[4096]; + +safef(dirName, sizeof dirName, "/dev/shm/trackDbCache/%s", db); +if (!isDirectory(dirName)) + { + makeDir(dirName); + chmod(dirName, 0777); + } + +char sharedMemoryName[4096]; +safef(sharedMemoryName, sizeof sharedMemoryName, "trackDbCache/%s", rTempName(db, "temp", "")); + +char tempFileName[4096]; +safef(tempFileName, sizeof tempFileName, "/dev/shm/%s", sharedMemoryName); + +int fd = shm_open(sharedMemoryName, oflags, 0666 ); +if (fd < 0) + { + unlink(tempFileName); + return; + } size_t psize = getpagesize(); unsigned long pageMask = psize - 1; // we should choose an address semi-randomly and make sure we can grab it rather than assume we can unsigned long address = 0x7000000; address = (address + psize - 1) & ~pageMask; u_char *mem; -struct trackDb *newList = NULL; -mem = (u_char *)newList; ftruncate(fd, 0); ftruncate(fd, size); mem = (u_char *) mmap((void *)address, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); struct lm *lm = lmInitWMem(mem, size); struct hash *superHash = newHash(8); -newList = lmCloneTdbList(lm, list, NULL, superHash); -msync((void *)address, size, MS_SYNC); +lmCloneTdbList(lm, list, NULL, superHash); + +unsigned long memUsed = lmUsed(lm); + +msync((void *)address, memUsed, MS_SYNC); +ftruncate(fd, memUsed); + munmap((void *)address, size); close(fd); -return mapSharedMemTrackDb(file, address, size); +char fileName[4096]; +safef(fileName, sizeof fileName, "/dev/shm/trackDbCache/%s/%ld", db, address); + +mustRename(tempFileName, fileName); }