Untitled

 avatar
unknown
plain_text
a month ago
3.1 kB
8
Indexable
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>

// Define UDMABUF structures and constants
struct udmabuf_create {
    uint32_t memfd;
    uint32_t offset;
    uint32_t size;
    uint32_t flags;
};

#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create)

// Utility function to measure time in nanoseconds
uint64_t get_ns(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
}

// Test IOCTL method
int test_ioctl(size_t buffer_size, int iterations) {
    int fd = open("/dev/udmabuf0", O_RDWR);
    if (fd < 0) {
        printf("Failed to open udmabuf device: %s\n", strerror(errno));
        return -1;
    }

    uint64_t total_time = 0;
    struct udmabuf_create create = {
        .size = buffer_size,
        .flags = 0,
    };

    for (int i = 0; i < iterations; i++) {
        uint64_t start = get_ns();
        
        int dmabuf_fd = ioctl(fd, UDMABUF_CREATE, &create);
        if (dmabuf_fd < 0) {
            printf("IOCTL failed: %s\n", strerror(errno));
            close(fd);
            return -1;
        }

        uint64_t end = get_ns();
        total_time += (end - start);
        
        close(dmabuf_fd);
    }

    close(fd);
    return total_time / iterations;
}

// Test mmap method
int test_mmap(size_t buffer_size, int iterations) {
    uint64_t total_time = 0;

    for (int i = 0; i < iterations; i++) {
        uint64_t start = get_ns();
        
        int fd = open("/dev/udmabuf0", O_RDWR);
        if (fd < 0) {
            printf("Failed to open udmabuf device: %s\n", strerror(errno));
            return -1;
        }

        void *buffer = mmap(NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (buffer == MAP_FAILED) {
            printf("mmap failed: %s\n", strerror(errno));
            close(fd);
            return -1;
        }

        uint64_t end = get_ns();
        total_time += (end - start);
        
        munmap(buffer, buffer_size);
        close(fd);
    }

    return total_time / iterations;
}

int main(int argc, char **argv) {
    // Test different buffer sizes
    size_t sizes[] = {4096, 16384, 65536, 262144, 1048576};
    int iterations = 1000;

    printf("Buffer Size\tIOCTL (ns)\tmmap (ns)\tDifference\n");
    printf("----------------------------------------------------------\n");

    for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) {
        int ioctl_time = test_ioctl(sizes[i], iterations);
        int mmap_time = test_mmap(sizes[i], iterations);

        if (ioctl_time >= 0 && mmap_time >= 0) {
            printf("%8zu\t%10d\t%10d\t%10d\n", 
                sizes[i], ioctl_time, mmap_time, mmap_time - ioctl_time);
        } else {
            printf("%8zu\tFailed\tFailed\tN/A\n", sizes[i]);
        }
    }

    return 0;
}
Leave a Comment