@@ -54,6 +54,22 @@ typedef struct ipc_opened_cache_t {
54
54
55
55
ipc_opened_cache_global_t * IPC_OPENED_CACHE_GLOBAL = NULL ;
56
56
57
+ // Returns value of the UMF_MAX_OPENED_IPC_HANDLES environment variable
58
+ // or 0 if it is not set.
59
+ static size_t umfIpcCacheGlobalInitMaxOpenedHandles (void ) {
60
+ const char * max_size_str = getenv ("UMF_MAX_OPENED_IPC_HANDLES" );
61
+ if (max_size_str ) {
62
+ char * endptr ;
63
+ size_t max_size = strtoul (max_size_str , & endptr , 10 );
64
+ if (* endptr == '\0' ) {
65
+ return max_size ;
66
+ }
67
+ LOG_ERR ("Invalid value of UMF_MAX_OPENED_IPC_HANDLES: %s" ,
68
+ max_size_str );
69
+ }
70
+ return 0 ;
71
+ }
72
+
57
73
umf_result_t umfIpcCacheGlobalInit (void ) {
58
74
umf_result_t ret = UMF_RESULT_SUCCESS ;
59
75
ipc_opened_cache_global_t * cache_global =
@@ -78,8 +94,7 @@ umf_result_t umfIpcCacheGlobalInit(void) {
78
94
goto err_mutex_destroy ;
79
95
}
80
96
81
- // TODO: make max_size configurable via environment variable
82
- cache_global -> max_size = 0 ;
97
+ cache_global -> max_size = umfIpcCacheGlobalInitMaxOpenedHandles ();
83
98
cache_global -> cur_size = 0 ;
84
99
cache_global -> lru_list = NULL ;
85
100
@@ -191,7 +206,19 @@ umf_result_t umfIpcOpenedCacheGet(ipc_opened_cache_handle_t cache,
191
206
if (entry == NULL && cache -> global -> max_size != 0 &&
192
207
cache -> global -> cur_size >= cache -> global -> max_size ) {
193
208
// If max_size is set and the cache is full, evict the least recently used entry.
194
- entry = cache -> global -> lru_list -> prev ;
209
+ // we need to search for the least recently used entry with ref_count == 0
210
+ // The utlist implementation of the doubly-linked list keeps a tail pointer in head->prev
211
+ ipc_opened_cache_entry_t * candidate = cache -> global -> lru_list -> prev ;
212
+ do {
213
+ uint64_t ref_count = 0 ;
214
+ utils_atomic_load_acquire_u64 (& candidate -> ref_count ,
215
+ & ref_count );
216
+ if (ref_count == 0 ) {
217
+ entry = candidate ;
218
+ break ;
219
+ }
220
+ candidate = candidate -> prev ;
221
+ } while (candidate != cache -> global -> lru_list -> prev );
195
222
}
196
223
197
224
if (entry ) { // we have eviction candidate
@@ -244,3 +271,20 @@ umf_result_t umfIpcOpenedCacheGet(ipc_opened_cache_handle_t cache,
244
271
245
272
return ret ;
246
273
}
274
+
275
+ umf_result_t
276
+ umfIpcHandleMappedCacheRelease (ipc_opened_cache_value_t * cacheValue ) {
277
+ if (!cacheValue ) {
278
+ LOG_ERR ("cacheValue is NULL" );
279
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
280
+ }
281
+
282
+ // get pointer to the entry
283
+ ipc_opened_cache_entry_t * entry =
284
+ (ipc_opened_cache_entry_t * )((char * )cacheValue -
285
+ offsetof(ipc_opened_cache_entry_t , value ));
286
+ // decrement the ref count
287
+ utils_atomic_decrement_u64 (& entry -> ref_count );
288
+
289
+ return UMF_RESULT_SUCCESS ;
290
+ }
0 commit comments