file_io: Yield while loading directories

Yield at an interval during the loading of directory entries as well as
while sorting them in order to not starve the poll functions.

The maximum time between calls to `user_io_poll` in the main loop were
measured while loading a folder containing 29026 entries:

 - Original main-loop:       591ms
 - With coroutines + yields:  29ms

The amount of time it takes to load and sort the 29026 entries:

 - Original main-loop:       591ms
 - With coroutines + yields: 686ms

By increasing the value of `YieldIterations` in `file_io.cpp` the load
time will decrease while increasing the delay between calls to
`user_io_poll`.
This commit is contained in:
David Holm
2019-01-03 18:10:46 +01:00
parent 3908a7f583
commit abf99063dc

View File

@@ -22,9 +22,12 @@
#include "user_io.h"
#include "cfg.h"
#include "input.h"
#include "scheduler.h"
typedef std::vector<dirent> DirentVector;
static const size_t YieldIterations = 128;
DirentVector DirItem;
int iSelectedEntry = 0; // selected entry index
int iFirstEntry = 0;
@@ -520,6 +523,11 @@ struct DirentComp
{
bool operator()(const dirent& de1, const dirent& de2)
{
if (++iterations % YieldIterations == 0)
{
scheduler_yield();
}
if ((de1.d_type == DT_DIR) && !strcmp(de1.d_name, "..")) return true;
if ((de2.d_type == DT_DIR) && !strcmp(de2.d_name, "..")) return false;
@@ -545,6 +553,8 @@ struct DirentComp
return strcasecmp(de1.d_name, de2.d_name) < 0;
}
size_t iterations = 0;
};
static int get_stmode(const char *path)
@@ -635,8 +645,13 @@ int ScanDirectory(char* path, int mode, const char *extension, int options, cons
}
struct dirent *de;
while((de = readdir(d)))
for (size_t i = 0; (de = readdir(d)); i++)
{
if (0 < i && i % YieldIterations == 0)
{
scheduler_yield();
}
if (de->d_type == DT_DIR)
{
if (!strcmp(de->d_name, ".")) continue;