Exemplo n.º 1
0
/*
 * lipmem_memcpy_nodrain -- copy using libpmem pmem_memcpy_no_drain()
 * function without pmem_persist().
 */
static int
libpmem_memcpy_nodrain(void *dest, void *source, size_t len)
{
	pmem_memcpy_nodrain(dest, source, len);

	return 0;
}
Exemplo n.º 2
0
static void *
pmem_memcpy_nodrain_wrapper(void *pmemdest, const void *src, size_t len,
		unsigned flags)
{
	(void) flags;
	return pmem_memcpy_nodrain(pmemdest, src, len);
}
Exemplo n.º 3
0
Arquivo: blk.c Projeto: jebtang/nvml
/*
 * nswrite -- (internal) write data to the namespace encapsulating the BTT
 *
 * This routine is provided to btt_init() to allow the btt module to
 * do I/O on the memory pool containing the BTT layout.
 */
static int
nswrite(void *ns, int lane, const void *buf, size_t count, off_t off)
{
	struct pmemblk *pbp = (struct pmemblk *)ns;

	LOG(13, "pbp %p lane %d count %zu off %lld",
			pbp, lane, count, (long long)off);

	if (off + count > pbp->datasize) {
		ERR("offset + count (%lld) past end of data area (%zu)",
				(long long)off + count, pbp->datasize);
		errno = EINVAL;
		return -1;
	}

	void *dest = pbp->data + off;

#ifdef DEBUG
	/* grab debug write lock */
	if ((errno = pthread_mutex_lock(&pbp->write_lock))) {
		ERR("!pthread_mutex_lock");
		return -1;
	}
#endif

	/* unprotect the memory (debug version only) */
	RANGE_RW(dest, count);

	if (pbp->is_pmem)
		pmem_memcpy_nodrain(dest, buf, count);
	else
		memcpy(dest, buf, count);

	/* protect the memory again (debug version only) */
	RANGE_RO(dest, count);

#ifdef DEBUG
	/* release debug write lock */
	if ((errno = pthread_mutex_unlock(&pbp->write_lock)))
		ERR("!pthread_mutex_unlock");
#endif

	if (pbp->is_pmem)
		pmem_drain();
	else
		pmem_msync(dest, count);

	return 0;
}
Exemplo n.º 4
0
Arquivo: blk.c Projeto: xguo/nvml
/*
 * nswrite -- (internal) write data to the namespace encapsulating the BTT
 *
 * This routine is provided to btt_init() to allow the btt module to
 * do I/O on the memory pool containing the BTT layout.
 */
static int
nswrite(void *ns, unsigned lane, const void *buf, size_t count,
		uint64_t off)
{
	struct pmemblk *pbp = (struct pmemblk *)ns;

	LOG(13, "pbp %p lane %u count %zu off %ju", pbp, lane, count, off);

	if (off + count > pbp->datasize) {
		ERR("offset + count (%zu) past end of data area (%zu)",
				off + count, pbp->datasize);
		errno = EINVAL;
		return -1;
	}

	void *dest = (char *)pbp->data + off;

#ifdef DEBUG
	/* grab debug write lock */
	util_mutex_lock(&pbp->write_lock);
#endif

	/* unprotect the memory (debug version only) */
	RANGE_RW(dest, count);

	if (pbp->is_pmem)
		pmem_memcpy_nodrain(dest, buf, count);
	else
		memcpy(dest, buf, count);

	/* protect the memory again (debug version only) */
	RANGE_RO(dest, count);

#ifdef DEBUG
	/* release debug write lock */
	util_mutex_unlock(&pbp->write_lock);
#endif

	if (pbp->is_pmem)
		pmem_drain();
	else
		pmem_msync(dest, count);

	return 0;
}
Exemplo n.º 5
0
/*
 * do_copy_to_pmem -- copy to pmem, postponing drain step until the end
 */
void
do_copy_to_pmem(char *pmemaddr, int srcfd, off_t len)
{
	char buf[BUF_LEN];
	int cc;

	/* copy the file, saving the last flush step to the end */
	while ((cc = read(srcfd, buf, BUF_LEN)) > 0) {
		pmem_memcpy_nodrain(pmemaddr, buf, cc);
		pmemaddr += cc;
	}

	if (cc < 0) {
		perror("read");
		exit(1);
	}

	/* perform final flush step */
	pmem_drain();
}
Exemplo n.º 6
0
int
main(int argc, char *argv[])
{
	char *dst;
	char *src;

	START(argc, argv, "pmem_movnt");

	src = MEMALIGN(64, 8192);
	dst = MEMALIGN(64, 8192);

	memset(src, 0x88, 8192);
	memset(dst, 0, 8192);

	for (size_t size = 1; size <= 4096; size *= 2) {
		memset(dst, 0, 4096);
		pmem_memcpy_nodrain(dst, src, size);
		ASSERTeq(memcmp(src, dst, size), 0);
		ASSERTeq(dst[size], 0);
	}

	for (size_t size = 1; size <= 4096; size *= 2) {
		memset(dst, 0, 4096);
		pmem_memmove_nodrain(dst, src, size);
		ASSERTeq(memcmp(src, dst, size), 0);
		ASSERTeq(dst[size], 0);
	}

	for (size_t size = 1; size <= 4096; size *= 2) {
		memset(dst, 0, 4096);
		pmem_memset_nodrain(dst, 0x77, size);
		ASSERTeq(dst[0], 0x77);
		ASSERTeq(dst[size - 1], 0x77);
		ASSERTeq(dst[size], 0);
	}

	FREE(dst);
	FREE(src);

	DONE(NULL);
}
Exemplo n.º 7
0
Arquivo: libpmem.c Projeto: arh/fio
static enum fio_q_status fio_libpmem_queue(struct thread_data *td,
					   struct io_u *io_u)
{
	fio_ro_check(td, io_u);
	io_u->error = 0;

	dprint(FD_IO, "DEBUG fio_libpmem_queue\n");

	switch (io_u->ddir) {
	case DDIR_READ:
		memcpy(io_u->xfer_buf, io_u->mmap_data, io_u->xfer_buflen);
		break;
	case DDIR_WRITE:
		dprint(FD_IO, "DEBUG mmap_data=%p, xfer_buf=%p\n",
				io_u->mmap_data, io_u->xfer_buf );
		dprint(FD_IO,"td->o.odirect %d \n",td->o.odirect);
		if (td->o.odirect) {
			pmem_memcpy_persist(io_u->mmap_data,
						io_u->xfer_buf,
						io_u->xfer_buflen);
		} else {
			pmem_memcpy_nodrain(io_u->mmap_data,
						io_u->xfer_buf,
						io_u->xfer_buflen);
		}
		break;
	case DDIR_SYNC:
	case DDIR_DATASYNC:
	case DDIR_SYNC_FILE_RANGE:
		break;
	default:
		io_u->error = EINVAL;
		break;
	}

	return FIO_Q_COMPLETED;
}
Exemplo n.º 8
0
Arquivo: log.c Projeto: harrybaa/nvml
/*
 * pmemlog_appendv -- add gathered data to a log memory pool
 */
int
pmemlog_appendv(PMEMlogpool *plp, const struct iovec *iov, int iovcnt)
{
    LOG(3, "plp %p iovec %p iovcnt %d", plp, iov, iovcnt);

    int ret = 0; // success
    int i;

    ASSERT(iovcnt > 0);

    if (plp->rdonly) {
        ERR("can't append to read-only log");
        errno = EROFS;
        return -1;
    }

    if ((errno = pthread_rwlock_wrlock(plp->rwlockp))) {
        ERR("!pthread_rwlock_wrlock");
        return -1;
    }

    /* get the current values */
    uint64_t end_offset = le64toh(plp->end_offset);
    uint64_t write_offset = le64toh(plp->write_offset);

    if (write_offset >= end_offset) {
        /* no space left */
        errno = ENOSPC;
        ERR("!pmemlog_appendv");
        ret = -1;
    } else {
        char *data = plp->addr;
        uint64_t count = 0;
        char *buf;

        /* calculate required space */
        for (i = 0; i < iovcnt; ++i)
            count += iov[i].iov_len;

        /* check if there is enough free space */
        if (count > (end_offset - write_offset)) {
            errno = ENOSPC;
            ret = -1;
        } else {
            /* append the data */
            for (i = 0; i < iovcnt; ++i) {
                buf = iov[i].iov_base;
                count = iov[i].iov_len;

                /*
                 * unprotect the log space range,
                 * where the new data will be stored
                 * (debug version only)
                 */
                RANGE_RW(&data[write_offset], count);

                if (plp->is_pmem)
                    pmem_memcpy_nodrain(&data[write_offset],
                                        buf, count);
                else
                    memcpy(&data[write_offset], buf, count);

                /*
                 * protect the log space range
                 * (debug version only)
                 */
                RANGE_RO(&data[write_offset], count);

                write_offset += count;
            }
        }
    }

    /* persist the data and the metadata only if there was no error */
    if (ret == 0)
        pmemlog_persist(plp, write_offset);

    int oerrno = errno;
    if ((errno = pthread_rwlock_unlock(plp->rwlockp)))
        ERR("!pthread_rwlock_unlock");
    errno = oerrno;

    return ret;
}
Exemplo n.º 9
0
Arquivo: log.c Projeto: harrybaa/nvml
/*
 * pmemlog_append -- add data to a log memory pool
 */
int
pmemlog_append(PMEMlogpool *plp, const void *buf, size_t count)
{
    int ret = 0;

    LOG(3, "plp %p buf %p count %zu", plp, buf, count);

    if (plp->rdonly) {
        ERR("can't append to read-only log");
        errno = EROFS;
        return -1;
    }

    if ((errno = pthread_rwlock_wrlock(plp->rwlockp))) {
        ERR("!pthread_rwlock_wrlock");
        return -1;
    }

    /* get the current values */
    uint64_t end_offset = le64toh(plp->end_offset);
    uint64_t write_offset = le64toh(plp->write_offset);

    if (write_offset >= end_offset) {
        /* no space left */
        errno = ENOSPC;
        ERR("!pmemlog_append");
        ret = -1;
    } else {
        /* make sure we don't write past the available space */
        if (count > (end_offset - write_offset)) {
            errno = ENOSPC;
            ERR("!pmemlog_append");
            ret = -1;
        } else {
            char *data = plp->addr;

            /*
             * unprotect the log space range,
             * where the new data will be stored
             * (debug version only)
             */
            RANGE_RW(&data[write_offset], count);

            if (plp->is_pmem)
                pmem_memcpy_nodrain(&data[write_offset],
                                    buf, count);
            else
                memcpy(&data[write_offset], buf, count);

            /* protect the log space range (debug version only) */
            RANGE_RO(&data[write_offset], count);

            write_offset += count;
        }
    }

    /* persist the data and the metadata only if there was no error */
    if (ret == 0)
        pmemlog_persist(plp, write_offset);

    int oerrno = errno;
    if ((errno = pthread_rwlock_unlock(plp->rwlockp)))
        ERR("!pthread_rwlock_unlock");
    errno = oerrno;

    return ret;
}