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:
guangli-dai 2026-07-26 17:04:34 -07:00 committed by Guangli Dai
parent c4158acac9
commit b62e7d2b06
9 changed files with 226 additions and 74 deletions

View file

@ -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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */