Skip to content

Commit

Permalink
make it even more asynchronous
Browse files Browse the repository at this point in the history
This change makes afatfs_poll() an internal static function, and
everything else works (almost) as before. The one difference is that
callbacks may be called directly from the routine where it was provided,
even before the routine returns. E.g. the callback for "unlink complete"
may be called before afatfs_funlink() returns.
  • Loading branch information
Risca committed Jun 18, 2021
1 parent 153a009 commit b965f5b
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 31 deletions.
55 changes: 48 additions & 7 deletions lib/asyncfatfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ static afatfs_t afatfs;
static void afatfs_fileOperationContinue(afatfsFile_t *file);
static uint8_t* afatfs_fileLockCursorSectorForWrite(afatfsFilePtr_t file);
static uint8_t* afatfs_fileRetainCursorSectorForRead(afatfsFilePtr_t file);
static void afatfs_fileOperationsPoll();
static void afatfs_poll();

static uint32_t roundUpTo(uint32_t value, uint32_t rounding)
{
Expand Down Expand Up @@ -639,6 +641,7 @@ static void afatfs_sdcardReadComplete(sdcardBlockOperation_e operation, uint32_t
break;
}
}
afatfs_poll();
}

/**
Expand Down Expand Up @@ -670,6 +673,7 @@ static void afatfs_sdcardWriteComplete(sdcardBlockOperation_e operation, uint32_
break;
}
}
afatfs_poll();
}

/**
Expand Down Expand Up @@ -904,6 +908,7 @@ static afatfsOperationStatus_e afatfs_cacheSector(uint32_t physicalSectorIndex,

if (cacheSectorIndex == -1) {
// We don't have enough free cache to service this request right now, try again later
afatfs_flush();
return AFATFS_OPERATION_IN_PROGRESS;
}

Expand Down Expand Up @@ -1454,7 +1459,7 @@ static afatfsOperationStatus_e afatfs_saveDirectoryEntry(afatfsFilePtr_t file, a
entry->fileSize = file->physicalSize;
break;
case AFATFS_SAVE_DIRECTORY_DELETED:
entry->filename[0] = FAT_DELETED_FILE_MARKER;
entry->filename[0] = (char)FAT_DELETED_FILE_MARKER;
//Fall through

case AFATFS_SAVE_DIRECTORY_FOR_CLOSE:
Expand Down Expand Up @@ -1560,6 +1565,9 @@ static afatfsOperationStatus_e afatfs_appendRegularFreeClusterContinue(afatfsFil
file->operation.operation = AFATFS_FILE_OPERATION_NONE;
}

// flush any pending writes
afatfs_flush();

return AFATFS_OPERATION_SUCCESS;
break;
case AFATFS_APPEND_FREE_CLUSTER_PHASE_FAILURE:
Expand Down Expand Up @@ -2054,7 +2062,13 @@ static afatfsOperationStatus_e afatfs_fseekInternal(afatfsFilePtr_t file, uint32
opState->callback = callback;
opState->seekOffset = offset;

return AFATFS_OPERATION_IN_PROGRESS;
// Do an initial round of processing
if (afatfs_fseekInternalContinue(file)) {
return AFATFS_OPERATION_SUCCESS;
}
else {
return AFATFS_OPERATION_IN_PROGRESS;
}
}
}

Expand Down Expand Up @@ -2262,6 +2276,9 @@ static afatfsOperationStatus_e afatfs_extendSubdirectoryContinue(afatfsFile_t *d
opState->callback(directory);
}

// flush any pending writes
afatfs_flush();

return AFATFS_OPERATION_SUCCESS;
break;
case AFATFS_EXTEND_SUBDIRECTORY_PHASE_FAILURE:
Expand Down Expand Up @@ -2475,6 +2492,9 @@ static afatfsOperationStatus_e afatfs_ftruncateContinue(afatfsFilePtr_t file, bo
opState->callback(file);
}

// flush any pending writes
afatfs_flush();

return AFATFS_OPERATION_SUCCESS;
break;
}
Expand Down Expand Up @@ -2677,6 +2697,9 @@ static void afatfs_createFileContinue(afatfsFile_t *file)
}
}

// flush any pending writes
afatfs_flush();

file->operation.operation = AFATFS_FILE_OPERATION_NONE;
opState->callback(file);
break;
Expand Down Expand Up @@ -2742,6 +2765,8 @@ bool afatfs_funlink(afatfsFilePtr_t file, afatfsCallback_t callback)

file->operation.operation = AFATFS_FILE_OPERATION_UNLINK;

afatfs_funlinkContinue(file);

return true;
}

Expand Down Expand Up @@ -2795,6 +2820,11 @@ static afatfsFilePtr_t afatfs_createFile(afatfsFilePtr_t file, const char *name,

afatfs_createFileContinue(file);

if (file->operation.operation != AFATFS_FILE_OPERATION_CREATE_FILE && file->operation.operation != AFATFS_FILE_OPERATION_NONE) {
// file operation changed - process it
afatfs_fileOperationsPoll();
}

return file;
}

Expand Down Expand Up @@ -3394,6 +3424,7 @@ static void afatfs_initContinue()
afatfs_chdir(NULL);

afatfs.initPhase++;
goto doMore;
} else {
afatfs.lastError = AFATFS_ERROR_BAD_FILESYSTEM_HEADER;
afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL;
Expand All @@ -3407,9 +3438,19 @@ static void afatfs_initContinue()

afatfs_createFile(&afatfs.freeFile, AFATFS_FREESPACE_FILENAME, FAT_FILE_ATTRIBUTE_SYSTEM | FAT_FILE_ATTRIBUTE_READ_ONLY,
AFATFS_FILE_MODE_CREATE | AFATFS_FILE_MODE_RETAIN_DIRECTORY, afatfs_freeFileCreated);
if (afatfs.filesystemState != AFATFS_FILESYSTEM_STATE_FATAL
&& afatfs.initPhase != AFATFS_INITIALIZATION_FREEFILE_CREATING
) {
goto doMore;
}
break;
case AFATFS_INITIALIZATION_FREEFILE_CREATING:
afatfs_fileOperationContinue(&afatfs.freeFile);
if (afatfs.filesystemState != AFATFS_FILESYSTEM_STATE_FATAL
&& afatfs.initPhase != AFATFS_INITIALIZATION_FREEFILE_CREATING
) {
goto doMore;
}
break;
case AFATFS_INITIALIZATION_FREEFILE_FAT_SEARCH:
if (afatfs_findLargestContiguousFreeBlockContinue() == AFATFS_OPERATION_SUCCESS) {
Expand Down Expand Up @@ -3493,14 +3534,12 @@ static void afatfs_initContinue()

/**
* Check to see if there are any pending operations on the filesystem and perform a little work (without waiting on the
* sdcard). You must call this periodically.
* sdcard).
*/
void afatfs_poll()
static void afatfs_poll()
{
// Only attempt to continue FS operations if the card is present & ready, otherwise we would just be wasting time
if (sdcard_poll()) {
afatfs_flush();

if (sdcard_poll() && afatfs_flush()) {
switch (afatfs.filesystemState) {
case AFATFS_FILESYSTEM_STATE_INITIALIZATION:
afatfs_initContinue();
Expand Down Expand Up @@ -3577,6 +3616,8 @@ void afatfs_init()
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
sdcard_setProfilerCallback(afatfs_sdcardProfilerCallback);
#endif

afatfs_poll();
}

/**
Expand Down
1 change: 0 additions & 1 deletion lib/asyncfatfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ void afatfs_findLast(afatfsFilePtr_t directory);
bool afatfs_flush();
void afatfs_init();
bool afatfs_destroy(bool dirty);
void afatfs_poll();

uint32_t afatfs_getFreeBufferSpace();
uint32_t afatfs_getContiguousFreeSpace();
Expand Down
4 changes: 2 additions & 2 deletions tests/sdcard_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static void sdcard_continueReadBlock()
if (--sdcard.currentOperation.countdownTimer <= 0) {
uint64_t byteIndex = (uint64_t) sdcard.currentOperation.blockIndex * SDCARD_SIM_BLOCK_SIZE;

sdcard.state = SDCARD_STATE_READY;

fseeko(simFile, byteIndex, SEEK_SET);

if (fread(sdcard.currentOperation.buffer, sizeof(uint8_t), SDCARD_SIM_BLOCK_SIZE, simFile) == SDCARD_SIM_BLOCK_SIZE) {
Expand All @@ -93,8 +95,6 @@ static void sdcard_continueReadBlock()
fprintf(stderr, "SDCardSim: fread failed on underlying file\n");
exit(-1);
}

sdcard.state = SDCARD_STATE_READY;
}
}

Expand Down
30 changes: 18 additions & 12 deletions tests/test_file_delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,10 @@ bool continueSpaceReclaimTest(bool start)
afatfs_fopen("test.txt", "w+", spaceReclaimTestFileCreatedForEmpty);
break;
case SPACE_RECLAIM_TEST_STAGE_EMPTY_DELETE:
if (afatfs_funlink(testFile, spaceReclaimTestFileEmptyDeleted)) {
// Wait for the unlink to complete
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
if (!afatfs_funlink(testFile, spaceReclaimTestFileEmptyDeleted)) {
// retry later
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_EMPTY_DELETE;
}
break;
case SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_INIT:
Expand All @@ -204,9 +205,10 @@ bool continueSpaceReclaimTest(bool start)
}
break;
case SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_DELETE:
if (afatfs_funlink(testFile, spaceReclaimTestFileSolidAppendDeleted)) {
// Wait for the unlink to complete
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
if (!afatfs_funlink(testFile, spaceReclaimTestFileSolidAppendDeleted)) {
// retry later
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_DELETE;
}
break;
case SPACE_RECLAIM_TEST_STAGE_APPEND_INIT:
Expand All @@ -226,9 +228,10 @@ bool continueSpaceReclaimTest(bool start)
}
break;
case SPACE_RECLAIM_TEST_STAGE_APPEND_DELETE:
if (afatfs_funlink(testFile, spaceReclaimTestFileAppendDeleted)) {
// Wait for the unlink to complete
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE;
if (!afatfs_funlink(testFile, spaceReclaimTestFileAppendDeleted)) {
// retry later
reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_APPEND_DELETE;
}
break;
case SPACE_RECLAIM_TEST_STAGE_IDLE:
Expand Down Expand Up @@ -392,8 +395,11 @@ bool continueSpaceRetainTest(bool start, const char *fileMode)
break;
case SPACE_RETAIN_TEST_STAGE_UNLINK_B:
if (afatfs_funlink(retainTestFileB, retainTestFileBDeleted)) {
retainTestFileB = NULL;
retainTestStage = SPACE_RETAIN_TEST_STAGE_IDLE;
// need to check state again in case callback has already been triggered
if (retainTestStage == SPACE_RETAIN_TEST_STAGE_UNLINK_B) {
retainTestFileB = NULL;
retainTestStage = SPACE_RETAIN_TEST_STAGE_IDLE;
}
}
break;
case SPACE_RETAIN_TEST_STAGE_VERIFY_A_OPEN:
Expand Down Expand Up @@ -506,7 +512,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_file_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_file_size.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static void initFilesystem()
afatfs_init();

while (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY) {
afatfs_poll();
sdcard_poll();

if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_FATAL) {
fprintf(stderr, "[Fail] Fatal filesystem error during init\n");
Expand Down Expand Up @@ -252,7 +252,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_file_size_powerloss.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static void initFilesystem()
afatfs_init();

while (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY) {
afatfs_poll();
sdcard_poll();

if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_FATAL) {
fprintf(stderr, "[Fail] Fatal filesystem error during init\n");
Expand Down Expand Up @@ -248,7 +248,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_logging_workload.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_root_fill.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_subdir_fill.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_volume_fill.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ int main(int argc, char **argv)
bool keepGoing = true;

while (keepGoing) {
afatfs_poll();
sdcard_poll();

switch (afatfs_getFilesystemState()) {
case AFATFS_FILESYSTEM_STATE_READY:
Expand Down

0 comments on commit b965f5b

Please sign in to comment.