Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
test_pipe_cache_pressure.c
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
27
28#include <stdarg.h>
29#include <stddef.h>
30// cmocka.h declares `extern jmp_buf global_expect_assert_env' at file scope without including
31// <setjmp.h> itself. Same suppression as test_pipe_cache_policy.c, and for the same reason.
32#include <setjmp.h> // NOLINT(misc-include-cleaner)
33#include <stdint.h>
34#include <cmocka.h>
35
36#ifdef _WIN32
37#include "win/main_wrapper.h"
38#endif
39
40#define GIB ((size_t)1024 * 1024 * 1024)
41#define MIB ((size_t)1024 * 1024)
42
49
51static void _starts_at_the_plan(void **state)
52{
53 (void)state;
55
56 assert_int_equal(dt_pixelpipe_cache_pressure_budget(&p), 16 * GIB);
57 assert_int_equal(dt_pixelpipe_cache_pressure_cap(&p), 16 * GIB);
58 assert_int_equal(dt_pixelpipe_cache_pressure_reported(&p, 4 * GIB), 16 * GIB);
59}
60
63{
64 (void)state;
66
67 assert_int_equal(dt_pixelpipe_cache_pressure_shed_target(&p, 0.12, 8 * GIB), 6 * GIB);
68 assert_int_equal(dt_pixelpipe_cache_pressure_shed_target(&p, 0.40, 8 * GIB), 4 * GIB);
69
70 // Under the threshold nothing is shed, however much is held.
71 assert_int_equal(dt_pixelpipe_cache_pressure_shed_target(&p, 0.05, 8 * GIB),
73}
74
79{
80 (void)state;
82
86
87 // Nothing was shed, so nothing lowered the budget either.
88 assert_int_equal(dt_pixelpipe_cache_pressure_budget(&p), 16 * GIB);
89 assert_int_equal(p.mark, dt_pixelpipe_cache_pressure_mark_top(&p));
90}
91
94{
95 (void)state;
97
99 assert_int_equal(p.mark, 12 * GIB);
100 assert_int_equal(dt_pixelpipe_cache_pressure_budget(&p), 9 * GIB);
101
102 // Entries in use can leave the footprint above the ceiling; the ceiling only falls.
104 assert_int_equal(dt_pixelpipe_cache_pressure_budget(&p), 9 * GIB);
105}
106
117
123{
124 (void)state;
127
128 // The ceiling climbs, but never past 7/8 of the mark ...
129 for(int window = 0; window < 16; window++)
130 {
132 assert_true(p.ceiling <= dt_pixelpipe_cache_pressure_cap(&p));
133 }
134 assert_true(dt_pixelpipe_cache_pressure_budget(&p) < 12 * GIB);
135
136 // ... and the mark rises far more slowly than the ceiling: the 1/1024 of a plan per 2 s
137 // window is minutes of calm before the size that stalled is offered again.
138 assert_true(p.mark < 13 * GIB);
139}
140
144{
145 (void)state;
148
149 size_t previous = dt_pixelpipe_cache_pressure_budget(&p);
150 const size_t step = p.plan / 32;
151 for(int window = 0; window < 4096; window++)
152 {
153 if(!dt_pixelpipe_cache_pressure_relax(&p)) continue;
154 const size_t now = dt_pixelpipe_cache_pressure_budget(&p);
155 assert_true(now >= previous);
156 assert_true(now - previous <= step);
157 previous = now;
158 }
159 assert_int_equal(dt_pixelpipe_cache_pressure_budget(&p), 16 * GIB);
160}
161
165{
166 (void)state;
169
170 const size_t held = 11 * GIB; // still pinned by a running pipe
171 assert_true(dt_pixelpipe_cache_pressure_budget(&p) < held);
172 assert_int_equal(dt_pixelpipe_cache_pressure_reported(&p, held), held);
173}
174
175int main(int argc, char *argv[])
176{
177 const struct CMUnitTest tests[] = {
178 cmocka_unit_test(_starts_at_the_plan),
179 cmocka_unit_test(_sheds_a_share_of_what_is_held),
180 cmocka_unit_test(_an_empty_cache_is_not_the_cause),
183 cmocka_unit_test(_recovery_waits_under_the_mark),
186 };
187 return cmocka_run_group_tests(tests, NULL, NULL);
188}
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
GtkWidget * window
#define DT_PIXELPIPE_CACHE_PRESSURE_KEEP
static size_t dt_pixelpipe_cache_pressure_cap(const dt_pixelpipe_cache_pressure_t *p)
static size_t dt_pixelpipe_cache_pressure_shed_target(const dt_pixelpipe_cache_pressure_t *p, const double share, const size_t current)
static void dt_pixelpipe_cache_pressure_after_shed(dt_pixelpipe_cache_pressure_t *p, const size_t before, const size_t after)
static gboolean dt_pixelpipe_cache_pressure_relax(dt_pixelpipe_cache_pressure_t *p)
static void dt_pixelpipe_cache_pressure_init(dt_pixelpipe_cache_pressure_t *p, const size_t plan)
static size_t dt_pixelpipe_cache_pressure_reported(const dt_pixelpipe_cache_pressure_t *p, const size_t current)
static size_t dt_pixelpipe_cache_pressure_floor(const dt_pixelpipe_cache_pressure_t *p)
static size_t dt_pixelpipe_cache_pressure_mark_top(const dt_pixelpipe_cache_pressure_t *p)
static size_t dt_pixelpipe_cache_pressure_budget(const dt_pixelpipe_cache_pressure_t *p)
int main()
Definition prova.c:47
const float uint32_t state[4]
static void _recovery_reaches_the_plan_without_a_jump(void **state)
static void _the_budget_never_falls_under_the_floor(void **state)
static void _reported_budget_never_underflows_its_readers(void **state)
static void _a_shed_lowers_the_budget_to_what_is_left(void **state)
static void _an_empty_cache_is_not_the_cause(void **state)
static dt_pixelpipe_cache_pressure_t _plan_of(const size_t plan)
#define GIB
static void _recovery_waits_under_the_mark(void **state)
static void _starts_at_the_plan(void **state)
static void _sheds_a_share_of_what_is_held(void **state)