reduce syscalls on opening files - roll CLOEXEC into open

on linux open supports() O_CLOEXEC. add test case for this in meson
build and ifdef. this rolls 3 syscalls into 1 as we were doing open,
then fnctl to get and fcntl to set flags.

less syscalls is a good thing as syscalls are not cheap on some
architectures or systems. I've seen a syscall on 1 system take 2-3x
as long as another and another syscall in the same 2 system
comparison take 10x as long. depending on the syscall you may only
have a budget of something like 5000 syscalls "per frame" (60fps)
before you spend all of your frame time just in syscalls not
doing any processing, so we should keep these down if possible
and that is what this does.
This commit is contained in:
Carsten Haitzler 2019-07-26 10:15:47 +01:00
parent 24a49c8938
commit d19e435ff9
3 changed files with 35 additions and 6 deletions

View File

@ -123,6 +123,20 @@ function_checks = [
['dladdr', ['dlfcn.h'], ['dl'], '-D_GNU_SOURCE=1']
]
open_cloexec = cc.run('''#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv) {
int res = open(argv[0], O_RDONLY | O_CLOEXEC);
if (res < 0) return 1;
return 0;
}
''',
name : 'open works with O_CLOEXEC')
if open_cloexec.compiled() and open_cloexec.returncode() == 0
config_h.set10('HAVE_OPEN_CLOEXEC', true)
endif
strerror_r_char_p = cc.compiles('''#define _GNU_SOURCE
#include <string.h>
int func (void)

View File

@ -802,19 +802,28 @@ eina_file_open(const char *path, Eina_Bool shared)
if (!filename) return NULL;
if (shared)
{
#ifdef HAVE_SHM_OPEN
fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
goto on_error;
#else
goto on_error;
goto on_error;
#endif
}
else
fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
{
#ifdef HAVE_OPEN_CLOEXEC
fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO | O_CLOEXEC);
#else
fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
goto on_error;
#endif
}
if (fd < 0) goto on_error;
if (!eina_file_close_on_exec(fd, EINA_TRUE))
goto on_error;
if (fstat(fd, &file_stat))
goto on_error;

View File

@ -198,10 +198,16 @@ eina_mmap_safety_enabled_set(Eina_Bool enabled)
/* no zero page device - open it */
if (_eina_mmap_zero_fd < 0)
{
#ifdef HAVE_OPEN_CLOEXEC
_eina_mmap_zero_fd = open("/dev/zero", O_RDWR | O_CLOEXEC);
/* if we don;'t have one - fail to set up mmap safety */
if (_eina_mmap_zero_fd < 0) return EINA_FALSE;
#else
_eina_mmap_zero_fd = open("/dev/zero", O_RDWR);
/* if we don;'t have one - fail to set up mmap safety */
if (_eina_mmap_zero_fd < 0) return EINA_FALSE;
eina_file_close_on_exec(_eina_mmap_zero_fd, EINA_TRUE);
#endif
}
/* set up signal handler for SIGBUS */
sa.sa_sigaction = _eina_mmap_safe_sigbus;