From abafd66ba6297c8962808a07c05219cce7ba3c5f Mon Sep 17 00:00:00 2001 From: daniel Date: Sat, 2 Feb 2013 13:21:38 +0900 Subject: flash write backgrounding --- flash.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'flash.c') diff --git a/flash.c b/flash.c index db5a870..a46a511 100644 --- a/flash.c +++ b/flash.c @@ -1,6 +1,7 @@ #include "globals.h" #include "lcd.h" #include "version.h" +#include "flash.h" #include #include #include @@ -28,6 +29,16 @@ #define PERSIST_ERR_COULDNTWRITE 9 #define PERSIST_ERR_COUNDNTOPENFILE 10 +typedef struct { + FlashStruct *mem; + int addr; + int numbytes; +} userflashjob; + +static bool alive = true; +static GThread* userflashwritethread; +static GAsyncQueue* userflashwritequeue; + // crc32 routine static uint32_t crc32(uint8_t* buf, int count) @@ -287,7 +298,7 @@ static int readUserBlock(FlashStruct *mem) return 0; } -void writeUserBlock(FlashStruct *mem, int addr, int numbytes) +void writeUserBlockNow(FlashStruct *mem, int addr, int numbytes) { // *** There is a potential issue here.. if the mainfile is corrupt *** // *** and this gets called before readUserBlock then the *** @@ -327,6 +338,19 @@ void writeUserBlock(FlashStruct *mem, int addr, int numbytes) g_static_mutex_unlock (&mutex); } +void writeUserBlock(FlashStruct *mem, int addr, int numbytes) { + if (alive) { + userflashjob* job = g_malloc(sizeof(userflashjob)); + job->mem = mem; + job->addr = addr; + job->numbytes = numbytes; + g_async_queue_push(userflashwritequeue, job); + while (g_async_queue_length(userflashwritequeue) > 1) { + // spin + } + } +} + static void initFlashValues(FlashStruct *mem) { @@ -774,9 +798,35 @@ static void initFlashValues(FlashStruct *mem) } +static gpointer userflashwritethreadfunc(gpointer data) { + + printf("userflash write thread start\n"); + while (alive || g_async_queue_length(userflashwritequeue) > 0) { // make sure the last job in the queue gets written + GTimeVal whentotimeout; + g_get_current_time(&whentotimeout); + g_time_val_add(&whentotimeout, 250 * 1000); + userflashjob* job = (userflashjob*) g_async_queue_timed_pop(userflashwritequeue, &whentotimeout); + if(job != NULL){ + // process job + writeUserBlockNow(job->mem, job->addr, job->numbytes); + g_free(job); + } + } + printf("userflash write thread stop\n"); + + return NULL ; +} + +void startFlashWriterThread(){ + alive= true; + userflashwritequeue = g_async_queue_new(); + userflashwritethread = g_thread_create(userflashwritethreadfunc, NULL, true, NULL); +} void initFlash(FlashStruct *mem, gboolean reset_to_defaults, int starting_location) { + startFlashWriterThread(); + int read_size = readUserBlock(mem); if ( (read_size == 0) || @@ -806,9 +856,14 @@ void initFlash(FlashStruct *mem, gboolean reset_to_defaults, int starting_locati } } +void stopFlashWriterThread(){ + alive = false; + g_thread_join(userflashwritethread); // block until the write thread is totally finished. +} void fixFlash(FlashStruct *mem) { + int i, fix_initial_constants; float composite_min_burst_time[max_channels]; -- cgit