Untitled

 avatar
unknown
c_cpp
3 years ago
4.5 kB
8
Indexable
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/mman.h>
#define _GNU_SOURCE
#include <linux/mman.h>
#include <time.h>

#define PLAIN_DEV_PATH "/dev/mem"
#define PLAIN_PHSY_ADDR 0x800000000
#define DOORBELL_UIO_DEV_PATH "/dev/uio0"
#define PAGE_SIZE 4096
#define PLAIN_SIZE 1073741824
#define INTR_CMD 0x00

typedef struct ivshmem_uio_ptr{
    struct ivshmem_uio_reg{
    	uint32_t intr_mask;
        uint32_t intr_stat;
        uint32_t iv_pos;
        uint32_t doorbell;
        uint32_t iv_livelist;
    } registers;
    uint8_t pad[4096-sizeof(struct ivshmem_uio_reg)];
}IVSHMEM_REG;
typedef struct ivshmem_fifo_meta{
    struct ivshmem_fifo_offset{
        uint32_t r_offset;
        uint32_t w_offset;
        uint32_t max_bound;
    } offsets;
    uint8_t pad[2097152-sizeof(struct ivshmem_fifo_offset)];
}IVSHMEM_FIFO_META;

int main(int argc, char *argv[]){
    unsigned short dest_peer_id = (unsigned short)atoi(argv[1]);
    const uint32_t intr_msg = ((dest_peer_id & 0xffff) << 16) + (INTR_CMD & 0xffff);

    int plain_fd = -1, uio_fd = -1;
    if((plain_fd = open(PLAIN_DEV_PATH, O_ASYNC | O_RDWR)) < 0){
        perror("open(PLAIN_DEV_PATH)");
        exit(EXIT_FAILURE);
    }
    if((uio_fd = open(DOORBELL_UIO_DEV_PATH, O_ASYNC | O_RDWR)) < 0){
        perror("open(DOORBELL_UIO_DEV_PATH)");
        exit(EXIT_FAILURE);
    }

    int plain_map_option = MAP_SHARED; // ???
    if(PAGE_SIZE == 2097152){ // 2MB
        plain_map_option = MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_2MB; // ???
    }
    else if(PAGE_SIZE == 1073741824){ // 1GB
        plain_map_option = MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_1GB; // ???
    }
    int uio_map_option = MAP_SHARED; // ???
    /*
    if(PAGE_SIZE == 2097152){ // 2MB
        uio_map_option = MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_2MB; // ???
    }
    else if(PAGE_SIZE == 1073741824){ // 1GB
        uio_map_option = MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_1GB; // ???
    }
    */

    // Create epoll fd
    int flags = fcntl(uio_fd, F_GETFL, 0);
    fcntl(uio_fd, F_SETFL, flags | O_NONBLOCK);
    int uio_epoll_fd = epoll_create(1);
    struct epoll_event ev_epoll;
    ev_epoll.events = EPOLLIN | EPOLLET;
    ev_epoll.data.fd = uio_fd;
    epoll_ctl(uio_epoll_fd, EPOLL_CTL_ADD, uio_fd, &ev_epoll);
    struct epoll_event tmp_event[1];
    int num_fds = 0;

    void *plain_ptr = NULL;
    IVSHMEM_FIFO_META *plain_meta_ptr = NULL;
    void *plain_fifo_ptr = NULL;
    IVSHMEM_REG *uio_ptr = NULL;
    if((uio_ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, uio_map_option, uio_fd, 0)) == (void *) -1){
        perror("mmap(uio_fd)");
        exit(EXIT_FAILURE);
    }
    if((plain_ptr = mmap(NULL, PLAIN_SIZE, PROT_READ | PROT_WRITE, plain_map_option, plain_fd, PLAIN_PHSY_ADDR)) == (void *) -1){
        perror("mmap(plain_fd)");
        exit(EXIT_FAILURE);
    }

    plain_meta_ptr = plain_ptr;
    plain_fifo_ptr = plain_ptr + 2097152;
    plain_meta_ptr->offsets.r_offset = 0;
    plain_meta_ptr->offsets.w_offset = 0;
    plain_meta_ptr->offsets.max_bound = PLAIN_SIZE - 2097152;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    struct timespec begin, end;
    double time;
    void *buf_a, *buf_b;


    buf_a = malloc(1073741824);
    fprintf(stderr, "buf_a = malloc(1073741824)\n");
    buf_b = malloc(1073741824);
    fprintf(stderr, "buf_b = malloc(1073741824)\n");
    memset(buf_a, 0xff, 1073741824);
    fprintf(stderr, "memset(buf_a, 0xff, 1073741824)\n");
    memset(buf_b, 0x00, 1073741824);
    fprintf(stderr, "memset(buf_b, 0x00, 1073741824)\n");
    memset(plain_ptr, 0x00, 1073741824);
    fprintf(stderr, "memset(plain_ptr, 0x00, 1073741824)\n");

    printf("[local->local memcpy()] Starting...\n");
    clock_gettime(CLOCK_MONOTONIC, &begin);

    memcpy(buf_b, buf_a, 1073741824);

    clock_gettime(CLOCK_MONOTONIC, &end);

    time = (double)(end.tv_sec - begin.tv_sec) + ((double)(end.tv_nsec - begin.tv_nsec))/1000000000;
    printf("[local->local memcpy()] Elapsed time: %lf\n", time);

    printf("[local->ivshmem memcpy()] Starting...\n");
    clock_gettime(CLOCK_MONOTONIC, &begin);

    memcpy(plain_ptr, buf_a, 1073741824);

    clock_gettime(CLOCK_MONOTONIC, &end);

    time = (double)(end.tv_sec - begin.tv_sec) + ((double)(end.tv_nsec - begin.tv_nsec))/1000000000;
    printf("[local->ivshmem memcpy()] Elapsed time: %lf\n", time);

    return 0;
}