Untitled
#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