diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-04-03 11:16:39 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-10-16 14:50:39 +0100 |
commit | 1718cf5f8a39b922eba3ad1b3c9a9570188362b1 (patch) | |
tree | 4f6bf81cb4f382ca04856b98492289825133c5ae /firmware/common/dircache.c | |
parent | b16bae6fe624d30631bf83290e204197ab136c12 (diff) | |
download | rockbox-1718cf5f8a39b922eba3ad1b3c9a9570188362b1.tar.gz rockbox-1718cf5f8a39b922eba3ad1b3c9a9570188362b1.zip |
Convert a number of allocations to use buflib pinning
Several places in the codebase implemented an ad-hoc form of pinning;
they can be converted to use buflib pinning instead.
Change-Id: I4450be007e80f6c9cc9f56c2929fa4b9b85ebff3
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 60 |
1 files changed, 18 insertions, 42 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 8917b3348e..1d6371a6b5 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -249,7 +249,6 @@ static struct dircache_runinfo | |||
249 | /* cache buffer info */ | 249 | /* cache buffer info */ |
250 | int handle; /* buflib buffer handle */ | 250 | int handle; /* buflib buffer handle */ |
251 | size_t bufsize; /* size of buflib allocation - 1 */ | 251 | size_t bufsize; /* size of buflib allocation - 1 */ |
252 | int buflocked; /* don't move due to other allocs */ | ||
253 | union { | 252 | union { |
254 | void *p; /* address of buffer - ENTRYSIZE */ | 253 | void *p; /* address of buffer - ENTRYSIZE */ |
255 | struct dircache_entry *pentry; /* alias of .p to assist entry resolution */ | 254 | struct dircache_entry *pentry; /* alias of .p to assist entry resolution */ |
@@ -329,29 +328,9 @@ static inline void dumpster_clean_buffer(void *p, size_t size) | |||
329 | */ | 328 | */ |
330 | static int move_callback(int handle, void *current, void *new) | 329 | static int move_callback(int handle, void *current, void *new) |
331 | { | 330 | { |
332 | if (dircache_runinfo.buflocked) | 331 | (void)handle; (void)current; |
333 | return BUFLIB_CB_CANNOT_MOVE; | ||
334 | |||
335 | dircache_runinfo.p = new - ENTRYSIZE; | 332 | dircache_runinfo.p = new - ENTRYSIZE; |
336 | |||
337 | return BUFLIB_CB_OK; | 333 | return BUFLIB_CB_OK; |
338 | (void)handle; (void)current; | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * add a "don't move" lock count | ||
343 | */ | ||
344 | static inline void buffer_lock(void) | ||
345 | { | ||
346 | dircache_runinfo.buflocked++; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * remove a "don't move" lock count | ||
351 | */ | ||
352 | static inline void buffer_unlock(void) | ||
353 | { | ||
354 | dircache_runinfo.buflocked--; | ||
355 | } | 334 | } |
356 | 335 | ||
357 | 336 | ||
@@ -530,14 +509,14 @@ static void set_buffer(int handle, size_t size) | |||
530 | 509 | ||
531 | /** | 510 | /** |
532 | * remove the allocation from dircache control and return the handle | 511 | * remove the allocation from dircache control and return the handle |
512 | * Note that dircache must not be using the buffer! | ||
533 | */ | 513 | */ |
534 | static int reset_buffer(void) | 514 | static int reset_buffer(void) |
535 | { | 515 | { |
536 | int handle = dircache_runinfo.handle; | 516 | int handle = dircache_runinfo.handle; |
537 | if (handle > 0) | 517 | if (handle > 0) |
538 | { | 518 | { |
539 | /* don't mind .p; it might get changed by the callback even after | 519 | /* don't mind .p; buffer presence is determined by the following: */ |
540 | this call; buffer presence is determined by the following: */ | ||
541 | dircache_runinfo.handle = 0; | 520 | dircache_runinfo.handle = 0; |
542 | dircache_runinfo.bufsize = 0; | 521 | dircache_runinfo.bufsize = 0; |
543 | } | 522 | } |
@@ -1857,7 +1836,7 @@ static void reset_cache(void) | |||
1857 | */ | 1836 | */ |
1858 | static void build_volumes(void) | 1837 | static void build_volumes(void) |
1859 | { | 1838 | { |
1860 | buffer_lock(); | 1839 | core_pin(dircache_runinfo.handle); |
1861 | 1840 | ||
1862 | for (int i = 0; i < NUM_VOLUMES; i++) | 1841 | for (int i = 0; i < NUM_VOLUMES; i++) |
1863 | { | 1842 | { |
@@ -1903,12 +1882,14 @@ static void build_volumes(void) | |||
1903 | 1882 | ||
1904 | logf("Done, %ld KiB used", dircache.size / 1024); | 1883 | logf("Done, %ld KiB used", dircache.size / 1024); |
1905 | 1884 | ||
1906 | buffer_unlock(); | 1885 | core_unpin(dircache_runinfo.handle); |
1907 | } | 1886 | } |
1908 | 1887 | ||
1909 | /** | 1888 | /** |
1910 | * allocate buffer and return whether or not a synchronous build should take | 1889 | * allocate buffer and return whether or not a synchronous build should take |
1911 | * place; if 'realloced' is NULL, it's just a query about what will happen | 1890 | * place; if 'realloced' is NULL, it's just a query about what will happen |
1891 | * | ||
1892 | * Note this must be called with the dircache_lock() active. | ||
1912 | */ | 1893 | */ |
1913 | static int prepare_build(bool *realloced) | 1894 | static int prepare_build(bool *realloced) |
1914 | { | 1895 | { |
@@ -1958,16 +1939,14 @@ static int prepare_build(bool *realloced) | |||
1958 | *realloced = true; | 1939 | *realloced = true; |
1959 | reset_cache(); | 1940 | reset_cache(); |
1960 | 1941 | ||
1961 | buffer_lock(); | ||
1962 | |||
1963 | int handle = reset_buffer(); | 1942 | int handle = reset_buffer(); |
1964 | dircache_unlock(); | 1943 | dircache_unlock(); /* release lock held by caller */ |
1965 | 1944 | ||
1966 | core_free(handle); | 1945 | core_free(handle); |
1967 | 1946 | ||
1968 | handle = alloc_cache(size); | 1947 | handle = alloc_cache(size); |
1969 | 1948 | ||
1970 | dircache_lock(); | 1949 | dircache_lock(); /* reacquire lock */ |
1971 | 1950 | ||
1972 | if (dircache_runinfo.suspended && handle > 0) | 1951 | if (dircache_runinfo.suspended && handle > 0) |
1973 | { | 1952 | { |
@@ -1979,13 +1958,9 @@ static int prepare_build(bool *realloced) | |||
1979 | } | 1958 | } |
1980 | 1959 | ||
1981 | if (handle <= 0) | 1960 | if (handle <= 0) |
1982 | { | ||
1983 | buffer_unlock(); | ||
1984 | return -1; | 1961 | return -1; |
1985 | } | ||
1986 | 1962 | ||
1987 | set_buffer(handle, size); | 1963 | set_buffer(handle, size); |
1988 | buffer_unlock(); | ||
1989 | 1964 | ||
1990 | return syncbuild; | 1965 | return syncbuild; |
1991 | } | 1966 | } |
@@ -2384,9 +2359,9 @@ void dircache_fileop_create(struct file_base_info *dirinfop, | |||
2384 | if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename)) | 2359 | if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename)) |
2385 | { | 2360 | { |
2386 | /* scan-in the contents of the new directory at this level only */ | 2361 | /* scan-in the contents of the new directory at this level only */ |
2387 | buffer_lock(); | 2362 | core_pin(dircache_runinfo.handle); |
2388 | sab_process_dir(infop, false); | 2363 | sab_process_dir(infop, false); |
2389 | buffer_unlock(); | 2364 | core_unpin(dircache_runinfo.handle); |
2390 | } | 2365 | } |
2391 | } | 2366 | } |
2392 | 2367 | ||
@@ -2915,7 +2890,7 @@ void dircache_dump(void) | |||
2915 | 2890 | ||
2916 | if (dircache_runinfo.handle) | 2891 | if (dircache_runinfo.handle) |
2917 | { | 2892 | { |
2918 | buffer_lock(); | 2893 | core_pin(dircache_runinfo.handle); |
2919 | 2894 | ||
2920 | /* bin */ | 2895 | /* bin */ |
2921 | write(fdbin, dircache_runinfo.p + ENTRYSIZE, | 2896 | write(fdbin, dircache_runinfo.p + ENTRYSIZE, |
@@ -2985,7 +2960,7 @@ void dircache_dump(void) | |||
2985 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 2960 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
2986 | } | 2961 | } |
2987 | 2962 | ||
2988 | buffer_unlock(); | 2963 | core_unpin(dircache_runinfo.handle); |
2989 | } | 2964 | } |
2990 | 2965 | ||
2991 | dircache_unlock(); | 2966 | dircache_unlock(); |
@@ -3104,7 +3079,6 @@ int dircache_load(void) | |||
3104 | } | 3079 | } |
3105 | 3080 | ||
3106 | dircache_lock(); | 3081 | dircache_lock(); |
3107 | buffer_lock(); | ||
3108 | 3082 | ||
3109 | if (!dircache_is_clean(false)) | 3083 | if (!dircache_is_clean(false)) |
3110 | goto error; | 3084 | goto error; |
@@ -3113,6 +3087,7 @@ int dircache_load(void) | |||
3113 | dircache = maindata.dircache; | 3087 | dircache = maindata.dircache; |
3114 | 3088 | ||
3115 | set_buffer(handle, bufsize); | 3089 | set_buffer(handle, bufsize); |
3090 | core_pin(handle); | ||
3116 | hasbuffer = true; | 3091 | hasbuffer = true; |
3117 | 3092 | ||
3118 | /* convert back to in-RAM representation */ | 3093 | /* convert back to in-RAM representation */ |
@@ -3167,13 +3142,13 @@ int dircache_load(void) | |||
3167 | dircache_enable_internal(false); | 3142 | dircache_enable_internal(false); |
3168 | 3143 | ||
3169 | /* cache successfully loaded */ | 3144 | /* cache successfully loaded */ |
3145 | core_unpin(handle); | ||
3170 | logf("Done, %ld KiB used", dircache.size / 1024); | 3146 | logf("Done, %ld KiB used", dircache.size / 1024); |
3171 | rc = 0; | 3147 | rc = 0; |
3172 | error: | 3148 | error: |
3173 | if (rc < 0 && hasbuffer) | 3149 | if (rc < 0 && hasbuffer) |
3174 | reset_buffer(); | 3150 | reset_buffer(); |
3175 | 3151 | ||
3176 | buffer_unlock(); | ||
3177 | dircache_unlock(); | 3152 | dircache_unlock(); |
3178 | 3153 | ||
3179 | error_nolock: | 3154 | error_nolock: |
@@ -3199,8 +3174,9 @@ int dircache_save(void) | |||
3199 | if (fd < 0) | 3174 | if (fd < 0) |
3200 | return -1; | 3175 | return -1; |
3201 | 3176 | ||
3177 | /* it seems the handle *must* exist if this function is called */ | ||
3202 | dircache_lock(); | 3178 | dircache_lock(); |
3203 | buffer_lock(); | 3179 | core_pin(dircache_runinfo.handle); |
3204 | 3180 | ||
3205 | int rc = -1; | 3181 | int rc = -1; |
3206 | 3182 | ||
@@ -3269,7 +3245,7 @@ int dircache_save(void) | |||
3269 | that makes what was saved completely invalid */ | 3245 | that makes what was saved completely invalid */ |
3270 | rc = 0; | 3246 | rc = 0; |
3271 | error: | 3247 | error: |
3272 | buffer_unlock(); | 3248 | core_unpin(dircache_runinfo.handle); |
3273 | dircache_unlock(); | 3249 | dircache_unlock(); |
3274 | 3250 | ||
3275 | if (rc < 0) | 3251 | if (rc < 0) |