@@ -54,6 +54,22 @@ typedef struct ipc_opened_cache_t {
5454
5555ipc_opened_cache_global_t * IPC_OPENED_CACHE_GLOBAL = NULL ;
5656
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+
5773umf_result_t umfIpcCacheGlobalInit (void ) {
5874 umf_result_t ret = UMF_RESULT_SUCCESS ;
5975 ipc_opened_cache_global_t * cache_global =
@@ -78,8 +94,7 @@ umf_result_t umfIpcCacheGlobalInit(void) {
7894 goto err_mutex_destroy ;
7995 }
8096
81- // TODO: make max_size configurable via environment variable
82- cache_global -> max_size = 0 ;
97+ cache_global -> max_size = umfIpcCacheGlobalInitMaxOpenedHandles ();
8398 cache_global -> cur_size = 0 ;
8499 cache_global -> lru_list = NULL ;
85100
@@ -191,7 +206,18 @@ umf_result_t umfIpcOpenedCacheGet(ipc_opened_cache_handle_t cache,
191206 if (entry == NULL && cache -> global -> max_size != 0 &&
192207 cache -> global -> cur_size >= cache -> global -> max_size ) {
193208 // 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 (& candidate -> ref_count , & ref_count );
215+ if (ref_count == 0 ) {
216+ entry = candidate ;
217+ break ;
218+ }
219+ candidate = candidate -> prev ;
220+ } while (candidate != cache -> global -> lru_list -> prev );
195221 }
196222
197223 if (entry ) { // we have eviction candidate
@@ -244,3 +270,20 @@ umf_result_t umfIpcOpenedCacheGet(ipc_opened_cache_handle_t cache,
244270
245271 return ret ;
246272}
273+
274+ umf_result_t
275+ umfIpcHandleMappedCacheRelease (ipc_opened_cache_value_t * cacheValue ) {
276+ if (!cacheValue ) {
277+ LOG_ERR ("cacheValue is NULL" );
278+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
279+ }
280+
281+ // get pointer to the entry
282+ ipc_opened_cache_entry_t * entry =
283+ (ipc_opened_cache_entry_t * )((char * )cacheValue -
284+ offsetof(ipc_opened_cache_entry_t , value ));
285+ // decrement the ref count
286+ utils_atomic_decrement (& entry -> ref_count );
287+
288+ return UMF_RESULT_SUCCESS ;
289+ }
0 commit comments