diff options
author | daniel <danieruru@gmail.com> | 2013-02-04 18:38:35 +0900 |
---|---|---|
committer | daniel <danieruru@gmail.com> | 2013-02-04 18:38:35 +0900 |
commit | 47be01091dbed4d887b3123c0b2e649ff264d7f2 (patch) | |
tree | 3adbc6e7dd9291d09a30e815426234128651aba8 /flash.c | |
parent | abafd66ba6297c8962808a07c05219cce7ba3c5f (diff) |
Improve flash writing
Diffstat (limited to 'flash.c')
-rw-r--r-- | flash.c | 59 |
1 files changed, 45 insertions, 14 deletions
@@ -29,15 +29,24 @@ #define PERSIST_ERR_COULDNTWRITE 9 #define PERSIST_ERR_COUNDNTOPENFILE 10 +// flash writing queue bits +#define MAXQUEUEDJOBS 1 // This makes the queue a little bit pointless + // but you might want to queue a few more + typedef struct { FlashStruct *mem; int addr; int numbytes; } userflashjob; + static bool alive = true; +static GMutex writermutex; +static GCond writerwakeup; +static GCond writerqueueopen; static GThread* userflashwritethread; static GAsyncQueue* userflashwritequeue; +// // crc32 routine @@ -340,14 +349,20 @@ void writeUserBlockNow(FlashStruct *mem, int addr, int numbytes) void writeUserBlock(FlashStruct *mem, int addr, int numbytes) { if (alive) { + g_mutex_lock(&writermutex); + if (g_async_queue_length(userflashwritequeue) >= MAXQUEUEDJOBS) { + //printf("Queue closed, waiting\n"); + g_cond_wait(&writerqueueopen, &writermutex); + } + g_mutex_unlock(&writermutex); + userflashjob* job = g_malloc(sizeof(userflashjob)); - job->mem = mem; + job->mem = g_malloc(sizeof(FlashStruct)); + memcpy(job->mem, mem, sizeof(FlashStruct)); job->addr = addr; job->numbytes = numbytes; g_async_queue_push(userflashwritequeue, job); - while (g_async_queue_length(userflashwritequeue) > 1) { - // spin - } + g_cond_broadcast(&writerwakeup); } } @@ -800,19 +815,33 @@ static void initFlashValues(FlashStruct *mem) static gpointer userflashwritethreadfunc(gpointer data) { - printf("userflash write thread start\n"); + //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); + if (g_async_queue_length(userflashwritequeue) == 0){ // go into a sleep + g_mutex_lock(&writermutex); + g_cond_wait(&writerwakeup, &writermutex); + g_mutex_unlock(&writermutex); } + else { + userflashjob* job = (userflashjob*) g_async_queue_pop(userflashwritequeue); + if (job != NULL ) { + // process job + //printf("processing write\n"); + writeUserBlockNow(job->mem, job->addr, job->numbytes); + g_free(job->mem); + g_free(job); + } + // If someone is waiting for the queue to start accepting + // jobs again and we are tell them about it.. + if (g_async_queue_length(userflashwritequeue) < MAXQUEUEDJOBS) { + g_mutex_lock(&writermutex); + g_cond_broadcast(&writerqueueopen); + g_mutex_unlock(&writermutex); + } + } + } - printf("userflash write thread stop\n"); + //printf("userflash write thread stop\n"); return NULL ; } @@ -826,6 +855,7 @@ void startFlashWriterThread(){ void initFlash(FlashStruct *mem, gboolean reset_to_defaults, int starting_location) { startFlashWriterThread(); + atexit(stopFlashWriterThread); int read_size = readUserBlock(mem); @@ -858,6 +888,7 @@ void initFlash(FlashStruct *mem, gboolean reset_to_defaults, int starting_locati void stopFlashWriterThread(){ alive = false; + g_cond_broadcast(&writerwakeup); g_thread_join(userflashwritethread); // block until the write thread is totally finished. } |