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>
4547
4648DECL_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);
74106PRIVATE NONNULL ((1 )) void CC
75107dummy_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