mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-08-25 00:23:33 +03:00
Move file I/O and process ID retrieval to OS layer
Adds the File I/O and Process facilities to the OS layer, following the os.h dispatcher pattern:
This commit is contained in:
parent
c4158acac9
commit
b62e7d2b06
9 changed files with 226 additions and 74 deletions
|
|
@ -10,12 +10,14 @@
|
||||||
*
|
*
|
||||||
* os/posix/<module>.h - the default, used by every POSIX platform.
|
* os/posix/<module>.h - the default, used by every POSIX platform.
|
||||||
* os/<os>/<module>.h - an override, present ONLY when an OS specializes
|
* os/<os>/<module>.h - an override, present ONLY when an OS specializes
|
||||||
* that module.
|
* that module (e.g. windows/file.h).
|
||||||
*
|
*
|
||||||
* A dispatcher picks the OS-specific file when one exists and otherwise falls
|
* A dispatcher picks the OS-specific file when one exists and otherwise falls
|
||||||
* back to posix/ (guarded by JEMALLOC_OS_POSIX), so any POSIX platform builds
|
* back to posix/ (guarded by JEMALLOC_OS_POSIX), so any POSIX platform builds
|
||||||
* without being enumerated anywhere. A non-POSIX platform with no override
|
* without being enumerated anywhere. A non-POSIX platform with no override
|
||||||
* hits a #error.
|
* hits a #error. Each os/<module>.h also declares the function prototypes
|
||||||
|
* its backends must implement, so a backend with a missing or mismatched
|
||||||
|
* function fails to compile instead of silently diverging.
|
||||||
*
|
*
|
||||||
* Adding OS support for a module (only when existing module headers cannot be
|
* Adding OS support for a module (only when existing module headers cannot be
|
||||||
* reused): create os/<os>/<module>.h (and later a matching src body when
|
* reused): create os/<os>/<module>.h (and later a matching src body when
|
||||||
|
|
@ -23,4 +25,10 @@
|
||||||
* module: create os/<module>.h + os/posix/<module>.h and #include it below.
|
* module: create os/<module>.h + os/posix/<module>.h and #include it below.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Process */
|
||||||
|
#include "jemalloc/internal/os/process.h"
|
||||||
|
|
||||||
|
/* File I/O */
|
||||||
|
#include "jemalloc/internal/os/file.h"
|
||||||
|
|
||||||
#endif /* JEMALLOC_INTERNAL_OS_H */
|
#endif /* JEMALLOC_INTERNAL_OS_H */
|
||||||
|
|
|
||||||
36
include/jemalloc/internal/os/file.h
Normal file
36
include/jemalloc/internal/os/file.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_FILE_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_FILE_H
|
||||||
|
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
#include "jemalloc/internal/os/detect.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File I/O interface.
|
||||||
|
* Default: posix/. Override: Windows (CRT <io.h>).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Functions required for implementation in each backend. */
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t os_file_write_once(int fd, const void *buf,
|
||||||
|
size_t bytes);
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t os_file_read_once(int fd, void *buf,
|
||||||
|
size_t bytes);
|
||||||
|
/*
|
||||||
|
* Full retry-until-bytes-or-error versions of the above: loop over the
|
||||||
|
* _once primitive until target bytes are transferred or a non-retryable
|
||||||
|
* error occurs. Retrying on EINTR is a POSIX-only concept (Windows has no
|
||||||
|
* such signal-interruption semantics for this call), so that decision lives
|
||||||
|
* entirely in each backend rather than leaking into callers.
|
||||||
|
*/
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t os_file_write(int fd, const void *buf,
|
||||||
|
size_t bytes);
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t os_file_read(int fd, void *buf, size_t bytes);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include "jemalloc/internal/os/windows/file.h"
|
||||||
|
#elif defined(JEMALLOC_OS_POSIX)
|
||||||
|
# include "jemalloc/internal/os/posix/file.h"
|
||||||
|
#else
|
||||||
|
# error "OS layer: no file backend for this platform; add os/<os>/file.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_FILE_H */
|
||||||
68
include/jemalloc/internal/os/posix/file.h
Normal file
68
include/jemalloc/internal/os/posix/file.h
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_POSIX_FILE_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_POSIX_FILE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX file-I/O backend (read/write syscalls). Direct syscalls where
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
|
||||||
|
#ifdef JEMALLOC_USE_SYSCALL
|
||||||
|
# include <sys/syscall.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_write_once(int fd, const void *buf, size_t bytes) {
|
||||||
|
#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_write)
|
||||||
|
return (ssize_t)syscall(SYS_write, fd, buf, bytes);
|
||||||
|
#else
|
||||||
|
return (ssize_t)write(fd, buf, bytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_read_once(int fd, void *buf, size_t bytes) {
|
||||||
|
#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_read)
|
||||||
|
return (ssize_t)syscall(SYS_read, fd, buf, bytes);
|
||||||
|
#else
|
||||||
|
return (ssize_t)read(fd, buf, bytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_write(int fd, const void *buf, size_t bytes) {
|
||||||
|
size_t bytes_written = 0;
|
||||||
|
do {
|
||||||
|
ssize_t result = os_file_write_once(fd,
|
||||||
|
&((const byte_t *)buf)[bytes_written], bytes - bytes_written);
|
||||||
|
if (result < 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
bytes_written += result;
|
||||||
|
} while (bytes_written < bytes);
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_read(int fd, void *buf, size_t bytes) {
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
do {
|
||||||
|
ssize_t result = os_file_read_once(
|
||||||
|
fd, &((byte_t *)buf)[bytes_read], bytes - bytes_read);
|
||||||
|
if (result < 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else if (result == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_read += result;
|
||||||
|
} while (bytes_read < bytes);
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_POSIX_FILE_H */
|
||||||
17
include/jemalloc/internal/os/posix/process.h
Normal file
17
include/jemalloc/internal/os/posix/process.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_POSIX_PROCESS_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_POSIX_PROCESS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX process backend (getpid()).
|
||||||
|
*/
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE int
|
||||||
|
os_process_id(void) {
|
||||||
|
return (int)getpid();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_POSIX_PROCESS_H */
|
||||||
23
include/jemalloc/internal/os/process.h
Normal file
23
include/jemalloc/internal/os/process.h
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_PROCESS_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_PROCESS_H
|
||||||
|
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
#include "jemalloc/internal/os/detect.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process interface.
|
||||||
|
* Default: posix/. Override: Windows (GetCurrentProcessId).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Functions required for implementation in each backend. */
|
||||||
|
JEMALLOC_ALWAYS_INLINE int os_process_id(void);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include "jemalloc/internal/os/windows/process.h"
|
||||||
|
#elif defined(JEMALLOC_OS_POSIX)
|
||||||
|
# include "jemalloc/internal/os/posix/process.h"
|
||||||
|
#else
|
||||||
|
# error "OS layer: no process backend for this platform; add os/<os>/process.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_PROCESS_H */
|
||||||
52
include/jemalloc/internal/os/windows/file.h
Normal file
52
include/jemalloc/internal/os/windows/file.h
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_WINDOWS_FILE_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_WINDOWS_FILE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows file-I/O backend, via the C runtime io.h (_read/_write).
|
||||||
|
*/
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_write_once(int fd, const void *buf, size_t bytes) {
|
||||||
|
return (ssize_t)write(fd, buf, (unsigned int)bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_read_once(int fd, void *buf, size_t bytes) {
|
||||||
|
return (ssize_t)read(fd, buf, (unsigned int)bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No EINTR/signal-interruption semantics on Windows: never retry on error. */
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_write(int fd, const void *buf, size_t bytes) {
|
||||||
|
size_t bytes_written = 0;
|
||||||
|
do {
|
||||||
|
ssize_t result = os_file_write_once(fd,
|
||||||
|
&((const byte_t *)buf)[bytes_written], bytes - bytes_written);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
bytes_written += result;
|
||||||
|
} while (bytes_written < bytes);
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE ssize_t
|
||||||
|
os_file_read(int fd, void *buf, size_t bytes) {
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
do {
|
||||||
|
ssize_t result = os_file_read_once(
|
||||||
|
fd, &((byte_t *)buf)[bytes_read], bytes - bytes_read);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
} else if (result == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_read += result;
|
||||||
|
} while (bytes_read < bytes);
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_WINDOWS_FILE_H */
|
||||||
15
include/jemalloc/internal/os/windows/process.h
Normal file
15
include/jemalloc/internal/os/windows/process.h
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef JEMALLOC_INTERNAL_OS_WINDOWS_PROCESS_H
|
||||||
|
#define JEMALLOC_INTERNAL_OS_WINDOWS_PROCESS_H
|
||||||
|
|
||||||
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows process backend (GetCurrentProcessId()).
|
||||||
|
*/
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE int
|
||||||
|
os_process_id(void) {
|
||||||
|
return (int)GetCurrentProcessId();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* JEMALLOC_INTERNAL_OS_WINDOWS_PROCESS_H */
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "jemalloc/internal/jemalloc_preamble.h"
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
|
|
||||||
#include "jemalloc/internal/malloc_io.h"
|
#include "jemalloc/internal/malloc_io.h"
|
||||||
|
#include "jemalloc/internal/os.h"
|
||||||
#include "jemalloc/internal/util.h"
|
#include "jemalloc/internal/util.h"
|
||||||
|
|
||||||
#ifdef assert
|
#ifdef assert
|
||||||
|
|
@ -758,79 +759,14 @@ malloc_printf(const char *format, ...) {
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
malloc_write_fd_syscall(int fd, const void *buf, size_t count) {
|
|
||||||
#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_write)
|
|
||||||
/*
|
|
||||||
* Use syscall(2) rather than write(2) when possible in order to avoid
|
|
||||||
* the possibility of memory allocation within libc. This is necessary
|
|
||||||
* on FreeBSD; most operating systems do not have this problem though.
|
|
||||||
*
|
|
||||||
* syscall() returns long or int, depending on platform, so capture the
|
|
||||||
* result in the widest plausible type to avoid compiler warnings.
|
|
||||||
*/
|
|
||||||
return (ssize_t)syscall(SYS_write, fd, buf, count);
|
|
||||||
#else
|
|
||||||
return (ssize_t)write(fd, buf,
|
|
||||||
# ifdef _WIN32
|
|
||||||
(unsigned int)
|
|
||||||
# endif
|
|
||||||
count);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
malloc_write_fd(int fd, const void *buf, size_t count) {
|
malloc_write_fd(int fd, const void *buf, size_t count) {
|
||||||
size_t bytes_written = 0;
|
return os_file_write(fd, buf, count);
|
||||||
do {
|
|
||||||
ssize_t result = malloc_write_fd_syscall(fd,
|
|
||||||
&((const byte_t *)buf)[bytes_written],
|
|
||||||
count - bytes_written);
|
|
||||||
if (result < 0) {
|
|
||||||
#ifndef _WIN32
|
|
||||||
if (errno == EINTR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
bytes_written += result;
|
|
||||||
} while (bytes_written < count);
|
|
||||||
return bytes_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
malloc_read_fd_syscall(int fd, void *buf, size_t count) {
|
|
||||||
#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_read)
|
|
||||||
return (ssize_t)syscall(SYS_read, fd, buf, count);
|
|
||||||
#else
|
|
||||||
return (ssize_t)read(fd, buf,
|
|
||||||
# ifdef _WIN32
|
|
||||||
(unsigned int)
|
|
||||||
# endif
|
|
||||||
count);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
malloc_read_fd(int fd, void *buf, size_t count) {
|
malloc_read_fd(int fd, void *buf, size_t count) {
|
||||||
size_t bytes_read = 0;
|
return os_file_read(fd, buf, count);
|
||||||
do {
|
|
||||||
ssize_t result = malloc_read_fd_syscall(
|
|
||||||
fd, &((byte_t *)buf)[bytes_read], count - bytes_read);
|
|
||||||
if (result < 0) {
|
|
||||||
#ifndef _WIN32
|
|
||||||
if (errno == EINTR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
} else if (result == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytes_read += result;
|
|
||||||
} while (bytes_read < count);
|
|
||||||
return bytes_read;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "jemalloc/internal/jemalloc_internal_inlines_a.h"
|
#include "jemalloc/internal/jemalloc_internal_inlines_a.h"
|
||||||
#include "jemalloc/internal/malloc_io.h"
|
#include "jemalloc/internal/malloc_io.h"
|
||||||
#include "jemalloc/internal/mutex.h"
|
#include "jemalloc/internal/mutex.h"
|
||||||
|
#include "jemalloc/internal/os.h"
|
||||||
#include "jemalloc/internal/prof.h"
|
#include "jemalloc/internal/prof.h"
|
||||||
#include "jemalloc/internal/prof_data.h"
|
#include "jemalloc/internal/prof_data.h"
|
||||||
#include "jemalloc/internal/prof_inlines.h"
|
#include "jemalloc/internal/prof_inlines.h"
|
||||||
|
|
@ -484,11 +485,7 @@ prof_sys_thread_name_fetch(tsd_t *tsd) {
|
||||||
|
|
||||||
int
|
int
|
||||||
prof_getpid(void) {
|
prof_getpid(void) {
|
||||||
#ifdef _WIN32
|
return os_process_id();
|
||||||
return GetCurrentProcessId();
|
|
||||||
#else
|
|
||||||
return getpid();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue