Introduced two garbage collection mode: greedy and reluctant.
The greedy GC mode attempts to erase as many sectors as possible, and it is therefore a slow operation, since the flash driver must wait for about a second after erasing one sector. The former behavior was to always do a greedy GC if file reservations fails due to lack of space. The new reluctant GC stops after erasing one sector, and therefore we often do not have to wait if there is no file system operation in the time while the sector is being erased. We call the garbage collector using this mode when removing a file that is not a micro log file, since the remove function is called recursively for micro log files that are erased because the corresponding ordinary file is erased. This change increases the coffee test (examples/sky/test-coffee.c) speed from 9 to 5 seconds.
This commit is contained in:
parent
b730fb329d
commit
1425537a13
1 changed files with 14 additions and 2 deletions
|
@ -69,6 +69,11 @@
|
||||||
#define INVALID_PAGE ((coffee_page_t)-1)
|
#define INVALID_PAGE ((coffee_page_t)-1)
|
||||||
#define UNKNOWN_OFFSET ((cfs_offset_t)-1)
|
#define UNKNOWN_OFFSET ((cfs_offset_t)-1)
|
||||||
|
|
||||||
|
/* "Greedy" garbage collection erases as many sectors as possible. */
|
||||||
|
#define GC_GREEDY 0
|
||||||
|
/* "Reluctant" garbage collection stops after erasing one sector. */
|
||||||
|
#define GC_RELUCTANT 1
|
||||||
|
|
||||||
#define FD_VALID(fd) \
|
#define FD_VALID(fd) \
|
||||||
((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \
|
((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \
|
||||||
coffee_fd_set[(fd)].flags != COFFEE_FD_FREE)
|
coffee_fd_set[(fd)].flags != COFFEE_FD_FREE)
|
||||||
|
@ -258,7 +263,7 @@ get_sector_status(uint16_t sector, struct sector_stats *stats) {
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
cfs_garbage_collect(void)
|
collect_garbage(int mode)
|
||||||
{
|
{
|
||||||
uint16_t sector;
|
uint16_t sector;
|
||||||
struct sector_stats stats;
|
struct sector_stats stats;
|
||||||
|
@ -282,6 +287,9 @@ cfs_garbage_collect(void)
|
||||||
if(first_page < *next_free) {
|
if(first_page < *next_free) {
|
||||||
*next_free = first_page;
|
*next_free = first_page;
|
||||||
}
|
}
|
||||||
|
if(mode == GC_RELUCTANT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,6 +527,10 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!HDR_LOG(hdr)) {
|
||||||
|
collect_garbage(GC_RELUCTANT);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -548,7 +560,7 @@ reserve(const char *name, coffee_page_t pages, int allow_duplicates)
|
||||||
if(*gc_wait) {
|
if(*gc_wait) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
cfs_garbage_collect();
|
collect_garbage(GC_GREEDY);
|
||||||
page = find_contiguous_pages(pages);
|
page = find_contiguous_pages(pages);
|
||||||
if(page == INVALID_PAGE) {
|
if(page == INVALID_PAGE) {
|
||||||
watchdog_start();
|
watchdog_start();
|
||||||
|
|
Loading…
Reference in a new issue