예제 #1
0
파일: nocache.c 프로젝트: iillyyaa/nocache
static void store_pageinfo(int fd)
{
    int i;
    sigset_t mask, old_mask;

    sigfillset(&mask);
    sigprocmask(SIG_BLOCK, &mask, &old_mask);

    /* Hint we'll be using this file only once;
     * the Linux kernel will currently ignore this */
    fadv_noreuse(fd, 0, 0);

    /* check if there's space to store the info */
    pthread_mutex_lock(&lock);
    for(i = 0; i < max_fds && fds[i].fd != -1; i++)
        ;
    if(i == max_fds) {
        pthread_mutex_unlock(&lock);
        goto restoresigset; /* no space! */
    }
    fds[i].fd = fd;
    pthread_mutex_unlock(&lock);

    if(!fd_get_pageinfo(fd, &fds[i]))
        goto cleanup;

    DEBUG("store_pageinfo(fd=%d): pages in cache: %zd/%zd (%.1f%%)  [filesize=%.1fK, "
            "pagesize=%dK]\n", fd, fds[i].nr_pages_cached, fds[i].nr_pages,
             fds[i].nr_pages == 0 ? 0 : (100.0 * fds[i].nr_pages_cached / fds[i].nr_pages),
             1.0 * fds[i].size / 1024, (int) PAGESIZE / 1024);
    goto restoresigset;

    cleanup:
    fds[i].fd = -1;

    restoresigset:
    sigprocmask(SIG_SETMASK, &old_mask, NULL);

    return;
}
예제 #2
0
파일: nocache.c 프로젝트: ech0s7r/nocache
static void store_pageinfo(int fd)
{
    int i;
    int pages;
    struct stat st;
    void *file = NULL;
    unsigned char *pageinfo = NULL;
    sigset_t mask, old_mask;

    sigfillset(&mask);
    sigprocmask(SIG_BLOCK, &mask, &old_mask);

    if(fstat(fd, &st) == -1 || !S_ISREG(st.st_mode))
        goto restoresigset;

    /* Hint we'll be using this file only once;
     * the Linux kernel will currently ignore this */
    fadv_noreuse(fd, 0, 0);

    /* check if there's space to store the info */
    pthread_mutex_lock(&lock);
    for(i = 0; i < max_fds && fds[i].fd != -1; i++)
        ;
    if(i == max_fds) {
        pthread_mutex_unlock(&lock);
        goto restoresigset; /* no space! */
    }
    fds[i].fd = fd;
    pthread_mutex_unlock(&lock);

    /* If size is 0, mmap() will fail. We'll keep the fd stored, anyway, to
     * make sure the newly written pages will be freed (so no cleanup!). */
    if(st.st_size == 0) {
        fds[i].size = 0;
        fds[i].nr_pages = 0;
        fds[i].info = NULL;
        DEBUG("store_pageinfo(fd=%d): file size is ZERO, slot=%d\n", fd, i);
        goto restoresigset;
    }

    DEBUG("store_pageinfo(fd=%d): st.st_size=%ld\n", fd, st.st_size);

    fds[i].size = st.st_size;
    pages = fds[i].nr_pages = (st.st_size + PAGESIZE - 1) / PAGESIZE;
    pageinfo = calloc(sizeof(*pageinfo), pages);
    if(!pageinfo) {
        DEBUG("calloc failed: size=%d on fd=%d slot=%d\n", pages, fd, i);
        goto cleanup;
    }

    file = mmap(NULL, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
    if(file == MAP_FAILED) {
        DEBUG("store_pageinfo(fd=%d): mmap failed, errno:%d, %s\n",
            fd, errno, strerror(errno));
        goto cleanup;
    }

    if(mincore(file, st.st_size, pageinfo) == -1)
        goto cleanup;
    fds[i].info = pageinfo;

    munmap(file, st.st_size);

    if(debugfp != NULL) {
        int j, n = 0;
        for(j = 0; j < pages; j++)
            if(pageinfo[j] & 1)
                n++;
        DEBUG("store_pageinfo(fd=%d): pages in cache: %d/%d (%.1f%%)  [filesize=%.1fK, "
                "pagesize=%dK]\n", fd, n, pages, 100.0 * n / pages,
                 1.0 * st.st_size / 1024, (int) PAGESIZE / 1024);
    }
    goto restoresigset;

    cleanup:
    fds[i].fd = -1;
    if(pageinfo)
        free(pageinfo);
    if(file)
        munmap(file, st.st_size);

    restoresigset:
    sigprocmask(SIG_SETMASK, &old_mask, NULL);

    return;
}