5#include "region_impl.h"
6#include "region_file.h"
13#define INDEX_NIL SIZE_MAX
17 struct timespec last_access;
21CLOD_CONST
static size_t file_cache_size(
const uint8_t dims) {
22 const size_t unaligned =
sizeof(
struct file_cache) + sizeof(int64_t) * dims;
25static int64_t evictable_duration_ns(
const size_t cache_size) {
26 constexpr int64_t evictable_max = UINT64_C(10 * 1000 * 1000 * 1000);
27 static atomic
int cache_max = 0;
28 if (cache_max == 0) cache_max = num_procs();
29 return evictable_max - evictable_max / (int64_t)cache_max * (int64_t)cache_size;
31static int64_t timespec_diff_ns(
const struct timespec from,
const struct timespec to) {
33 if (ckd_sub(&sec_diff, to.tv_sec, from.tv_sec))
34 return to.tv_sec > from.tv_sec ? INT64_MAX : INT64_MIN;
35 if (ckd_mul(&sec_diff, sec_diff, 1000000000))
36 return to.tv_sec > from.tv_sec ? INT64_MAX : INT64_MIN;
38 if (ckd_sub(&nsec_diff, to.tv_nsec, from.tv_nsec))
39 return to.tv_nsec > from.tv_nsec ? INT64_MAX : INT64_MIN;
40 if (ckd_add(&nsec_diff, nsec_diff, sec_diff))
41 return to.tv_sec > from.tv_sec ? INT64_MAX : INT64_MIN;
45#define index(i) (assert(i < r->cache_len), (struct file_cache*)((char*)r->cache + i * file_cache_size(r->opts.dims)))
46#define fc_size file_cache_size(r->opts.dims)
50 if (!monotonic_now(&now)) {
55 const int64_t evictable_duration = evictable_duration_ns(r->cache_len);
57 size_t empty = INDEX_NIL;
58 for (
size_t i = 0; i < r->cache_len; i++) {
59 auto const fc = index(i);
61 if (fc->rf ==
nullptr) {
62 if (empty == INDEX_NIL) empty = i;
63 }
else if (memcmp(pos, fc->pos,
sizeof(fc->pos[0]) * r->opts.
dims) == 0) {
64 fc->last_access = now;
67 }
else if (timespec_diff_ns(fc->last_access, now) > evictable_duration) {
68 auto const res = region_file_close(fc->rf);
75 auto const res = region_file_open(r, &rf, pos, create);
78 if (empty == INDEX_NIL) {
79 void *
new = malloc((r->cache_len + 1) * fc_size);
82 region_file_close(rf);
86 memcpy(
new, r->cache, r->cache_len * fc_size);
89 empty = r->cache_len++;
92 auto const fc = index(empty);
94 fc->last_access = now;
95 memcpy(fc->pos, pos,
sizeof(fc->pos[0]) * r->opts.
dims);
102 for (
size_t i = 0; i < r->cache_len; i++) {
103 auto const fc = index(i);
105 auto const close_res = region_file_close(fc->rf);
@ CLOD_REGION_INVALID_USAGE