feat: rcmem

This commit is contained in:
2026-04-18 04:03:41 +02:00
parent 29683dfe1c
commit d829209488
5 changed files with 161 additions and 10 deletions

View File

@@ -14,6 +14,9 @@ target_include_directories(
add_executable(strings ${CMAKE_CURRENT_SOURCE_DIR}/app/strings.c) add_executable(strings ${CMAKE_CURRENT_SOURCE_DIR}/app/strings.c)
target_link_libraries(strings PRIVATE c-libs) target_link_libraries(strings PRIVATE c-libs)
add_executable(rc ${CMAKE_CURRENT_SOURCE_DIR}/app/rc.c)
target_link_libraries(rc PRIVATE c-libs)
include(CTest) include(CTest)
if(BUILD_TESTING) if(BUILD_TESTING)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
@@ -30,25 +33,26 @@ endif()
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(GNUInstallDirs) include(GNUInstallDirs)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install( install(
TARGETS c-libs TARGETS c-libs
EXPORT c-libs EXPORT c-libs
ARCHIVE DESTINATION lib ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION bin) RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/c-libs
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install( install(
EXPORT c-libs EXPORT c-libs
FILE c-libsTargets.cmake FILE c-libsTargets.cmake
NAMESPACE c-libs:: NAMESPACE c-libs::
DESTINATION lib/cmake/c-libs) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/c-libs)
configure_package_config_file( configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/c-libsConfig.cmake.in ${CMAKE_CURRENT_SOURCE_DIR}/c-libsConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/c-libsConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/c-libsConfig.cmake
INSTALL_DESTINATION lib/cmake/c-libs) INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/c-libs)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/c-libsConfig.cmake install(FILES ${CMAKE_CURRENT_BINARY_DIR}/c-libsConfig.cmake
DESTINATION lib/cmake/c-libs) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/c-libs)

35
app/rc.c Normal file
View File

@@ -0,0 +1,35 @@
#include <c-libs/rcmem.h>
#include <stdio.h>
#include <string.h>
void do_stuff(char *rc_s) { printf("Ptr %p -> %s\n", rc_s, rc_s); }
char *mk_rc_str(const char *s) {
char *rc_s = rc_new(20);
strncpy(rc_s, s, 20);
return rc_s;
}
void rc_info(void *rc) { printf("RC: %d, WRC: %d\n", rc_rc(rc), rc_wrc(rc)); }
static char *global_rc_s;
int main() {
char *rc_s = mk_rc_str("Hello World!");
global_rc_s = rc_ref(rc_s);
rc_info(rc_s);
rc_unref(rc_s);
rc_info(global_rc_s);
do_stuff(global_rc_s);
global_rc_s = rc_realloc(global_rc_s, 20480);
memset(global_rc_s, 'A', 20480);
global_rc_s[50] = '\0';
do_stuff(global_rc_s);
rc_unref(global_rc_s);
return 0;
}

View File

@@ -17,7 +17,9 @@
flake = { flake = {
overlays.default = final: prev: { overlays.default = final: prev: {
c-libs = final.callPackage ./nix/c-libs.nix {}; c-libs = (final.callPackage ./nix/c-libs.nix {}).overrideAttrs {
enableShared = true;
};
}; };
}; };
@@ -49,6 +51,8 @@
shellHook = '' shellHook = ''
export CMAKE_EXPORT_COMPILE_COMMANDS=ON export CMAKE_EXPORT_COMPILE_COMMANDS=ON
export BUILD_TESTING=ON export BUILD_TESTING=ON
export MANPATH="${pkgs.man-pages-posix}/share/man:$MANPATH"
export MANPATH="${pkgs.man-pages}/share/man:$MANPATH"
''; '';
}; };
}; };

108
include/c-libs/rcmem.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef CLIBS_RCMEM_H
#define CLIBS_RCMEM_H
#define _GNU_SOURCE
#include <memory.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/mman.h>
typedef struct {
uint32_t rc;
uint32_t wrc;
size_t len;
} RCHeader;
void *rc_new(size_t size) {
RCHeader *hdr = mmap(NULL, sizeof(RCHeader) + size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (hdr == MAP_FAILED) {
return NULL;
}
hdr->rc = 1;
hdr->len = size;
return hdr + 1;
}
void *rc_ref(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
hdr->rc += 1;
return ptr;
}
void *rc_wref(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
hdr->wrc += 1;
return ptr;
}
uint32_t rc_rc(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
return hdr->rc;
}
uint32_t rc_wrc(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
return hdr->wrc;
}
void *rc_clone(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
size_t len = sizeof(RCHeader) + hdr->len;
RCHeader *chdr = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
memcpy(chdr, hdr, len);
return chdr + 1;
}
void *rc_realloc(void *ptr, size_t size) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
size_t old_size = sizeof(RCHeader) + hdr->len;
size_t new_size = sizeof(RCHeader) + size;
RCHeader *new = mremap(hdr, old_size, new_size, MREMAP_MAYMOVE);
new->len = size;
if (new == MAP_FAILED) {
return NULL;
}
return new + 1;
}
uint32_t rc_wunref(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
hdr->wrc -= 1;
uint32_t wrc = hdr->wrc;
if (!hdr->wrc && !hdr->rc) {
munmap(hdr, sizeof(RCHeader) + hdr->len);
}
return wrc;
}
uint32_t rc_unref(void *ptr) {
RCHeader *hdr = ((RCHeader *)ptr) - 1;
hdr->rc -= 1;
uint32_t rc = hdr->rc;
if (!hdr->wrc && !hdr->rc) {
munmap(hdr, sizeof(RCHeader) + hdr->len);
}
return rc;
}
#endif

View File

@@ -10,12 +10,12 @@ stdenv.mkDerivation (finalAttrs: {
pname = "c-libs"; pname = "c-libs";
version = "0.1.0"; version = "0.1.0";
src = ../.; src = ../.;
outputs = ["out" "dev"];
nativeBuildInputs = [cmake] ++ lib.optional finalAttrs.doCheck pkg-config; nativeBuildInputs = [cmake] ++ lib.optional finalAttrs.doCheck pkg-config;
buildInputs = [] ++ lib.optional finalAttrs.doCheck criterion; buildInputs = [] ++ lib.optional finalAttrs.doCheck criterion;
cmakeFlags = [ cmakeFlags = [
(lib.cmakeBool "BUILD_TESTING" finalAttrs.doCheck) (lib.cmakeBool "BUILD_TESTING" finalAttrs.doCheck)
(lib.cmakeBool "BUILD_SHARED_LIBS" finalAttrs.enableShared or false)
]; ];
doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform; doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;