Skip to content

Commit 00a896f

Browse files
committed
Use /dev/void for dummy video buffers
1 parent 5956a26 commit 00a896f

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

kos/src/.sources

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ BEGIN
150150
BEGIN GROUP("libs.libvideo-gfx") { COMPILE, LINK, ARCHIVE, MCOPY };
151151
SET_OUTPUT_LIBDLL("libvideo-gfx")
152152
USELIB("libvideo-codec")
153+
LD_FLAGS({ "-fini=libvideo_gfx_fini" })
153154
SOURCE({
154155
"libvideo/gfx/*.c",
155156
"libvideo/gfx/fonts/*.c",

kos/src/libvideo/gfx/buffer/dummy.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include <sys/mman.h>
3636

3737
#include <assert.h>
38+
#include <atomic.h>
39+
#include <fcntl.h>
3840
#include <malloc.h>
3941
#include <stddef.h>
4042
#include <unistd.h>
@@ -45,21 +47,51 @@
4547

4648
DECL_BEGIN
4749

48-
PRIVATE WUNUSED byte_t *CC dummy_mmap(size_t num_bytes) {
49-
byte_t *result = (byte_t *)mmap(NULL, num_bytes, PROT_READ | PROT_WRITE,
50-
MAP_PRIVATE | MAP_ANON, -1, 0);
50+
PRIVATE fd_t dev_void = -1;
51+
PRIVATE WUNUSED fd_t CC get_dev_void(void) {
52+
fd_t result = atomic_read(&dev_void);
53+
if (result == -1) {
54+
#ifdef __KOS__
55+
result = open("/dev/void", O_RDWR);
56+
if (result < 0)
57+
#endif /* __KOS__ */
58+
{
59+
/* Shouldn't happen under KOS... */
60+
result = open("/dev/null", O_RDWR);
61+
}
62+
if (result >= 0) {
63+
fd_t old = atomic_cmpxch_val(&dev_void, -1, result);
64+
if unlikely(old != -1) {
65+
(void)close(result);
66+
result = old;
67+
}
68+
}
69+
}
70+
return result;
71+
}
72+
73+
/* Hooked by build script via `-fini=libvideo_gfx_fini' */
74+
INTERN void libvideo_gfx_fini(void) {
75+
if (dev_void != -1)
76+
(void)close(dev_void);
77+
}
78+
79+
PRIVATE WUNUSED byte_t *CC mmap_void(size_t num_bytes) {
80+
byte_t *result;
81+
fd_t dev_void = get_dev_void();
82+
if unlikely(dev_void < 0)
83+
return NULL;
84+
result = (byte_t *)mmap(NULL, num_bytes, PROT_READ | PROT_WRITE,
85+
MAP_PRIVATE | MAP_FILE, dev_void, 0);
5186
if (result == MAP_FAILED) {
5287
result = NULL;
5388
} else {
5489
assert(result != NULL);
55-
/* XXX: "MADV_FREE" is a one-time hint, but we'd
56-
* need it in the form of a permanent effect */
57-
(void)madvise(result, num_bytes, MADV_FREE);
5890
}
5991
return result;
6092
}
6193

62-
PRIVATE void CC dummy_munmap(byte_t *data, size_t num_bytes) {
94+
PRIVATE void CC munmap_void(byte_t *data, size_t num_bytes) {
6395
(void)munmap(data, num_bytes);
6496
}
6597

@@ -74,7 +106,7 @@ PRIVATE struct video_buffer_dummy_awref current_dummy = AWREF_INIT(NULL);
74106
PRIVATE NONNULL((1)) void CC
75107
dummy_destroy(struct video_buffer_dummy *__restrict self) {
76108
awref_cmpxch(&current_dummy, self, NULL);
77-
dummy_munmap(self->vbd_data, self->vbd_size);
109+
munmap_void(self->vbd_data, self->vbd_size);
78110
free(self);
79111
}
80112

@@ -100,7 +132,7 @@ libvideo_buffer_getdummy(size_t num_bytes) {
100132
if unlikely(!result)
101133
goto err;
102134
aligned_num_bytes = CEIL_ALIGN(num_bytes, getpagesize());
103-
result->vbd_data = dummy_mmap(aligned_num_bytes);
135+
result->vbd_data = mmap_void(aligned_num_bytes);
104136
if unlikely(!result->vbd_data)
105137
goto err_r;
106138
result->vbd_size = aligned_num_bytes;

0 commit comments

Comments
 (0)