mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-08-17 21:03:54 +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/<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
|
||||
* back to posix/ (guarded by JEMALLOC_OS_POSIX), so any POSIX platform builds
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Process */
|
||||
#include "jemalloc/internal/os/process.h"
|
||||
|
||||
/* File I/O */
|
||||
#include "jemalloc/internal/os/file.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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue