33#include "../win32.h"
44#include "fscache.h"
55#include "config.h"
6+ #include "../../mem-pool.h"
67
78static volatile long initialized ;
89static DWORD dwTlsIndex ;
@@ -17,6 +18,7 @@ static CRITICAL_SECTION mutex;
1718struct fscache {
1819 volatile long enabled ;
1920 struct hashmap map ;
21+ struct mem_pool * mem_pool ;
2022 unsigned int lstat_requests ;
2123 unsigned int opendir_requests ;
2224 unsigned int fscache_requests ;
@@ -106,11 +108,11 @@ static void fsentry_init(struct fsentry *fse, struct fsentry *list,
106108/*
107109 * Allocate an fsentry structure on the heap.
108110 */
109- static struct fsentry * fsentry_alloc (struct fsentry * list , const char * name ,
111+ static struct fsentry * fsentry_alloc (struct fscache * cache , struct fsentry * list , const char * name ,
110112 size_t len )
111113{
112114 /* overallocate fsentry and copy the name to the end */
113- struct fsentry * fse = xmalloc ( sizeof (struct fsentry ) + len + 1 );
115+ struct fsentry * fse = mem_pool_alloc ( cache -> mem_pool , sizeof (struct fsentry ) + len + 1 );
114116 char * nm = ((char * ) fse ) + sizeof (struct fsentry );
115117 memcpy (nm , name , len );
116118 nm [len ] = 0 ;
@@ -133,35 +135,28 @@ inline static void fsentry_addref(struct fsentry *fse)
133135}
134136
135137/*
136- * Release the reference to an fsentry, frees the memory if its the last ref .
138+ * Release the reference to an fsentry.
137139 */
138140static void fsentry_release (struct fsentry * fse )
139141{
140142 if (fse -> list )
141143 fse = fse -> list ;
142144
143- if (InterlockedDecrement (& (fse -> refcnt )))
144- return ;
145-
146- while (fse ) {
147- struct fsentry * next = fse -> next ;
148- free (fse );
149- fse = next ;
150- }
145+ InterlockedDecrement (& (fse -> refcnt ));
151146}
152147
153148/*
154149 * Allocate and initialize an fsentry from a WIN32_FIND_DATA structure.
155150 */
156- static struct fsentry * fseentry_create_entry (struct fsentry * list ,
151+ static struct fsentry * fseentry_create_entry (struct fscache * cache , struct fsentry * list ,
157152 const WIN32_FIND_DATAW * fdata )
158153{
159154 char buf [MAX_PATH * 3 ];
160155 int len ;
161156 struct fsentry * fse ;
162157 len = xwcstoutf (buf , fdata -> cFileName , ARRAY_SIZE (buf ));
163158
164- fse = fsentry_alloc (list , buf , len );
159+ fse = fsentry_alloc (cache , list , buf , len );
165160
166161 fse -> st_mode = file_attr_to_st_mode (fdata -> dwFileAttributes );
167162 fse -> st_size = (((off64_t ) (fdata -> nFileSizeHigh )) << 32 )
@@ -178,7 +173,7 @@ static struct fsentry *fseentry_create_entry(struct fsentry *list,
178173 * Dir should not contain trailing '/'. Use an empty string for the current
179174 * directory (not "."!).
180175 */
181- static struct fsentry * fsentry_create_list (const struct fsentry * dir ,
176+ static struct fsentry * fsentry_create_list (struct fscache * cache , const struct fsentry * dir ,
182177 int * dir_not_found )
183178{
184179 wchar_t pattern [MAX_LONG_PATH + 2 ]; /* + 2 for "\*" */
@@ -217,13 +212,13 @@ static struct fsentry *fsentry_create_list(const struct fsentry *dir,
217212 }
218213
219214 /* allocate object to hold directory listing */
220- list = fsentry_alloc (NULL , dir -> name , dir -> len );
215+ list = fsentry_alloc (cache , NULL , dir -> name , dir -> len );
221216 list -> st_mode = S_IFDIR ;
222217
223218 /* walk directory and build linked list of fsentry structures */
224219 phead = & list -> next ;
225220 do {
226- * phead = fseentry_create_entry (list , & fdata );
221+ * phead = fseentry_create_entry (cache , list , & fdata );
227222 phead = & (* phead )-> next ;
228223 } while (FindNextFileW (h , & fdata ));
229224
@@ -235,7 +230,7 @@ static struct fsentry *fsentry_create_list(const struct fsentry *dir,
235230 if (err == ERROR_NO_MORE_FILES )
236231 return list ;
237232
238- /* otherwise free the list and return error */
233+ /* otherwise release the list and return error */
239234 fsentry_release (list );
240235 errno = err_win_to_posix (err );
241236 return NULL ;
@@ -258,7 +253,10 @@ static void fscache_add(struct fscache *cache, struct fsentry *fse)
258253 */
259254static void fscache_clear (struct fscache * cache )
260255{
261- hashmap_free (& cache -> map , 1 );
256+ mem_pool_discard (cache -> mem_pool , 0 );
257+ cache -> mem_pool = NULL ;
258+ mem_pool_init (& cache -> mem_pool , 0 );
259+ hashmap_free (& cache -> map , 0 );
262260 hashmap_init (& cache -> map , (hashmap_cmp_fn )fsentry_cmp , NULL , 0 );
263261 cache -> lstat_requests = cache -> opendir_requests = 0 ;
264262 cache -> fscache_misses = cache -> fscache_requests = 0 ;
@@ -311,7 +309,7 @@ static struct fsentry *fscache_get(struct fscache *cache, struct fsentry *key)
311309 }
312310
313311 /* create the directory listing */
314- fse = fsentry_create_list (key -> list ? key -> list : key , & dir_not_found );
312+ fse = fsentry_create_list (cache , key -> list ? key -> list : key , & dir_not_found );
315313
316314 /* leave on error (errno set by fsentry_create_list) */
317315 if (!fse ) {
@@ -321,7 +319,7 @@ static struct fsentry *fscache_get(struct fscache *cache, struct fsentry *key)
321319 * empty, which for all practical matters is the same
322320 * thing as far as fscache is concerned).
323321 */
324- fse = fsentry_alloc (key -> list -> list ,
322+ fse = fsentry_alloc (cache , key -> list -> list ,
325323 key -> list -> name , key -> list -> len );
326324 fse -> st_mode = 0 ;
327325 hashmap_add (& cache -> map , fse );
@@ -399,6 +397,7 @@ int fscache_enable(size_t initial_size)
399397 * '4' was determined empirically by testing several repos
400398 */
401399 hashmap_init (& cache -> map , (hashmap_cmp_fn )fsentry_cmp , NULL , initial_size * 4 );
400+ mem_pool_init (& cache -> mem_pool , 0 );
402401 if (!TlsSetValue (dwTlsIndex , cache ))
403402 BUG ("TlsSetValue error" );
404403 }
@@ -430,7 +429,8 @@ void fscache_disable(void)
430429 "total requests/misses %u/%u\n" ,
431430 cache -> lstat_requests , cache -> opendir_requests ,
432431 cache -> fscache_requests , cache -> fscache_misses );
433- fscache_clear (cache );
432+ mem_pool_discard (cache -> mem_pool , 0 );
433+ hashmap_free (& cache -> map , 0 );
434434 free (cache );
435435 }
436436
@@ -612,6 +612,8 @@ void fscache_merge(struct fscache *dest)
612612 while ((e = hashmap_iter_next (& iter )))
613613 hashmap_add (& dest -> map , e );
614614
615+ mem_pool_combine (dest -> mem_pool , cache -> mem_pool );
616+
615617 dest -> lstat_requests += cache -> lstat_requests ;
616618 dest -> opendir_requests += cache -> opendir_requests ;
617619 dest -> fscache_requests += cache -> fscache_requests ;
0 commit comments