Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
sys_resources.h
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef DT_SYSTEM_SYS_RESOURCES_H
20#define DT_SYSTEM_SYS_RESOURCES_H
21
22/* Memory and worker budgets. The values are owned by the orchestrator
23 * (darktable.c, which fills dt_sys_resources_t once at startup), but the
24 * consumers are low-level compute units -- the pixelpipe cache, tiling, the mipmap
25 * cache, the memory arena -- which must not have to include the whole application
26 * to ask how much RAM they may use. */
27
28#include <glib.h>
29#include <stddef.h>
30#include <stdint.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/* System-wide free RAM Ansel always leaves to the OS and other applications, in bytes.
37 * Absolute on purpose: the kernel's needs do not scale with installed RAM, so a fixed
38 * reserve is both sufficient on a small machine and non-wasteful on a large one.
39 * Overridable through the `memory_pressure_floor` conf key (MiB, 0 = use this). */
40#define DT_MEMORY_PRESSURE_FLOOR_DEFAULT ((int64_t)200 * 1024 * 1024)
41
42typedef struct dt_sys_resources_t
43{
44 size_t total_memory; // All RAM on system
45 size_t mipmap_memory; // RAM allocated to mipmap cache
46 size_t headroom_memory; // RAM left to OS & other Apps
47 size_t pixelpipe_memory; // RAM used by the pixelpipe cache (approx.)
48 size_t pressure_floor_memory; // System-wide available RAM under which we shed caches
50
52
53// Number of workers, on top of reserved workers (1 for main preview, 1 for thumbnail in darkroom)
54// This is currently set to 2, so 4 workers total, without user config.
55// Workers will process a queue of jobs that they share together (except for reserved ones).
56// It is useless to use more than 2 workers
57// since those jobs very often lock some mutex that prevents concurrent running.
58// All jobs finding an idle worker will "start" immediately, as far as the OS knows from outside the program,
59// but may do nothing internally except for waiting a mutex locked by another worker/thread.
60// In that situation, we loose the ability to flush the queue, since jobs are "running".
61// So it's better to have few workers with long queues, rather
62// than many workers, to be able to control queued jobs.
64
65// Get the remaining memory available for pipeline allocations,
66// once we subtracted caches memory and headroom from system memory
68
69// Get the maximum size for the whole mipmap cache
70size_t dt_get_mipmap_mem();
71
72// Get the total memory (bytes) the process budgets against: physical RAM, capped by
73// a container/cgroup limit and the host_memory_limit config. Set once at startup by
74// dt_configure_runtime_performance(), never mutated afterwards.
75size_t dt_get_total_mem(void);
76
77// Probe the system for currently-available (free + reclaimable) physical RAM, in bytes.
78// This is a live system-wide measurement, unrelated to our internal budgets: it shrinks
79// when OTHER applications allocate memory. On Linux it also honors a cgroup v2 memory
80// limit (containers, Flatpak, systemd slices) when one is set. Returns 0 when the
81// platform gives us no way to know — callers must treat 0 as "no information", not as
82// "out of memory".
83// The value is cached for a few tens of milliseconds (the probe reads several /proc and
84// /sys files), so it may lag reality by that much.
86
87// Drop the cached probe value so the next dt_get_system_available_mem() re-reads the OS.
88// For callers that just changed the situation themselves (freeing caches) and need the
89// resulting number to be ground truth rather than a pre-change snapshot.
91
92// System-wide available RAM floor (bytes) under which caches must be shed to
93// keep the OS and other applications breathing, regardless of anselrc budgets.
94// See dt_configure_runtime_performance() for how it is derived.
96
98
99#ifdef __cplusplus
100}
101#endif
102
103#endif // DT_SYSTEM_SYS_RESOURCES_H
104
105// clang-format off
106// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
107// vim: shiftwidth=2 expandtab tabstop=2 cindent
108// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
109// clang-format on
void dt_invalidate_system_available_mem(void)
Definition darktable.c:2348
size_t dt_get_system_available_mem(void)
Definition darktable.c:2329
int dt_worker_threads()
Definition darktable.c:2371
void dt_print_mem_usage()
Definition darktable.c:2576
size_t dt_get_memory_pressure_floor(void)
Definition darktable.c:2408
size_t dt_get_total_mem(void)
Definition darktable.c:2403
size_t dt_get_mipmap_mem()
Definition darktable.c:2398
void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui)
Definition darktable.c:2413
size_t dt_get_available_mem()
Definition darktable.c:2376