Skip to content

Add accounting allocator and native memory pressure C-API#244

Open
ramezgerges wants to merge 1 commit into
mono:skiasharpfrom
ramezgerges:dev/native-memory-pressure-monitor
Open

Add accounting allocator and native memory pressure C-API#244
ramezgerges wants to merge 1 commit into
mono:skiasharpfrom
ramezgerges:dev/native-memory-pressure-monitor

Conversation

@ramezgerges

@ramezgerges ramezgerges commented May 25, 2026

Copy link
Copy Markdown

Description of Change

Add src/c/sk_memory_skiasharp.cpp, an accounting variant of src/ports/SkMemory_malloc.cpp. Behaviorally identical to the upstream allocator, but every successful sk_malloc/sk_realloc/sk_free updates an atomic int64 counter (measured via malloc_usable_size / _msize / malloc_size). A registered callback fires whenever the counter drifts +/- threshold bytes since the last notification, claimed via CAS so only one thread fires per crossing.

Expose two new functions in include/c/sk_graphics.h:

uint64_t sk_graphics_get_native_memory_allocated(void);
void sk_graphics_set_native_memory_threshold_callback(
sk_native_memory_threshold_proc callback,
uint64_t threshold_bytes);

BUILD.gn: link the SkiaSharp variant instead of the upstream allocator. The sksl tool's separate build (gn/sksl.gni) keeps the default malloc.

Lets the managed layer report Skia's native byte usage to the GC via GC.AddMemoryPressure / RemoveMemoryPressure without polling.

SkiaSharp Issue

Related to mono/SkiaSharp#1288

API Changes

uint64_t sk_graphics_get_native_memory_allocated(void);
void sk_graphics_set_native_memory_threshold_callback(
sk_native_memory_threshold_proc callback,
uint64_t threshold_bytes);

Behavioral Changes

None.

Required SkiaSharp PR

Requires mono/SkiaSharp#4067

PR Checklist

  • Rebased on top of skiasharp at time of PR
  • Changes adhere to coding standard
  • Updated documentation

Add a process-wide allocation counter and threshold-crossing notification
that the managed SkiaSharp layer uses to drive GC.AddMemoryPressure /
RemoveMemoryPressure without polling.

The bookkeeping (atomic counter, threshold watermark, CAS-claimed
crossing logic, malloc_usable_size dispatching, public C-API) lives in
a dedicated src/c/sk_memory.cpp / include/c/sk_memory.h pair in the
SkiaSharp C shim. The upstream allocator
(src/ports/SkMemory_malloc.cpp) gains only a forward declaration of
two extern "C" hook functions and a single call site in each of
sk_malloc_flags / sk_free / sk_realloc_throw -- ~25 added lines total,
no upstream lines removed.

The new public C-API:

  uint64_t sk_memory_get_native_allocated(void);
  void     sk_memory_set_threshold_callback(
               sk_memory_threshold_proc callback,
               uint64_t                 threshold_bytes);

A NULL callback or zero threshold disables notifications; the counter
keeps updating.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ramezgerges ramezgerges force-pushed the dev/native-memory-pressure-monitor branch from 90bf5a1 to 34d86c7 Compare June 1, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant