From bfcca3a220f2c44d41e7b9a4bd9c50b30c54c2f0 Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 3 Aug 2023 09:26:35 +0200 Subject: [PATCH] gol: Use memory-mapped IO --- apps/gol.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/apps/gol.cpp b/apps/gol.cpp index 36b13863..02399a7c 100644 --- a/apps/gol.cpp +++ b/apps/gol.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ static int g_fb_height; static int g_fd; static Cell* g_cells; +static char* g_fb; static Result fill_cells() { @@ -47,27 +49,29 @@ static Cell& find_cell(int row, int column) static constexpr int BYTES_PER_PIXEL = 4; -static char* g_buf; - static void draw_cells() { - lseek(g_fd, 0, SEEK_SET); - const int CELL_WIDTH = g_fb_width / g_num_columns; const int CELL_HEIGHT = g_fb_height / g_num_rows; for (int i = 0; i < g_num_rows; i++) { - memset(g_buf, 0, g_fb_width * BYTES_PER_PIXEL); for (int j = 0; j < g_num_columns; j++) { - auto& cell = find_cell(i, j); - if (cell.state) memset(g_buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), 0xff, CELL_WIDTH * BYTES_PER_PIXEL); - } + char* buf = g_fb + (i * g_fb_width * CELL_HEIGHT * BYTES_PER_PIXEL); - for (int j = 0; j < CELL_HEIGHT; j++) { write(g_fd, g_buf, g_fb_width * BYTES_PER_PIXEL); } + auto& cell = find_cell(i, j); + u8 color = cell.state ? 0xff : 0x00; + for (int k = 0; k < CELL_HEIGHT; k++) + { + memset(buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), color, CELL_WIDTH * BYTES_PER_PIXEL); + buf += g_fb_width * BYTES_PER_PIXEL; + } + } } + + msync(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL, MS_SYNC); } static int find_neighbors(int row, int column) @@ -137,7 +141,7 @@ Result luna_main(int argc, char** argv) else srand((unsigned)time(NULL)); - g_fd = open("/dev/fb0", O_WRONLY); + g_fd = open("/dev/fb0", O_RDWR); if (g_fd < 0) { perror("gol: cannot open framebuffer for writing"); @@ -149,7 +153,13 @@ Result luna_main(int argc, char** argv) TRY(fill_cells()); - g_buf = (char*)TRY(calloc_impl(g_fb_width, BYTES_PER_PIXEL)); + g_fb = + (char*)mmap(nullptr, g_fb_height * g_fb_width * BYTES_PER_PIXEL, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0); + if (g_fb == MAP_FAILED) + { + perror("gol: cannot map framebuffer into memory"); + return 1; + } draw_cells(); @@ -162,5 +172,8 @@ Result luna_main(int argc, char** argv) usleep(delay_at_end * 1000); + munmap(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL); + free(g_cells); + return 0; }