//----------------------------------------------------------------------------- // new file scenario / etc. static void flush_write_buffers(void) { chSemWait(&write_buffer_semaphore); memset(&write_buffers, 0, sizeof(write_buffers)); for ( int8_t idx = 0 ; idx < BUFFER_COUNT ; idx++ ) write_buffers[idx].current_idx = -1; flush_counters(); chSemSignal(&write_buffer_semaphore); }
int save_local_data(char * text, int len){ save_bin_cfg(); //Save the quickbar spells save_quickspells(); //Save recipes save_recipes(); // save el.ini if asked if (write_ini_on_exit) write_el_ini (); // save notepad contents if the file was loaded if (notepad_loaded) notepad_save_file(); save_exploration_map(); flush_counters(); // for the new questlog, this actually just saves any pending changes // should be renamed when NEW_QUESTLOG #def is removed unload_questlog(); save_item_lists(); LOG_TO_CONSOLE(c_green1, "Local files saved, asking server to save too..."); return 0; }
static THD_FUNCTION(thLogger, arg) { (void)arg; chRegSetThreadName("Logger"); // These nested while() loops require some explanation. // If the current state is running, we should be in the inner loop // always - just storing, etc. But if the SD is not ready yet, // we will be in the outer loop, flushing buffers, and signalling // uint32_t logger_buffers_written = 0; current_msg.global_count = 0; while( !chThdShouldTerminateX() && LS_EXITING != logger_state) { flush_write_buffers(); int8_t current_idx = -1; systime_t sleep_until = chVTGetSystemTimeX() + MS2ST(5); while( !chThdShouldTerminateX() && LS_RUNNING == logger_state ) { if ( current_idx == -1 ) { current_idx = new_write_buffer_idx_to_fill(); if ( current_idx == -1 ) { // no buffers? sleep and try again chThdSleepMilliseconds(1); continue; } } // here we'll have a good buffer to fill up until it's all full! write_buffer_t * wb = &write_buffers[current_idx]; { kbb_current_msg_t * lm = &wb->buffer[wb->current_idx]; chSysLock(); // make sure that we complete a write uninterrupted memcpy(lm, ¤t_msg, sizeof(current_msg)); chSysUnlock(); kbt_getRTC(&lm->rtc); uint8_t * buf = (uint8_t*) lm; // NOTHING must get written after this, ok? lm->header.checksum = calc_checksum_16(buf+KBB_CHECKSUM_START, KBB_MSG_SIZE-KBB_CHECKSUM_START); } // chTimeNow() will roll over every ~49 days // @TODO: make this code handle that (or not, 49 days is a lot!!) while ( sleep_until < chVTGetSystemTimeX() ) { // this code handles for when we skipped a writing-slot // i'm counting a skipped msg as a write error current_msg.write_errors++; current_msg.msg_num++; sleep_until += MS2ST(5); } chThdSleepUntil(sleep_until); sleep_until += MS2ST(5); // Next deadline current_msg.msg_num++; current_msg.global_count++; // @TODO: fix this! if ( current_msg.msg_num%2048 == 0 ) // we write 1MB every 2048 msgs { kbs_setSDCFree(--cardsize_MB); } wb->current_idx++; if ( wb->current_idx == BUFFER_SIZE ) { // we're full up, return it for a new one return_write_buffer_idx_after_filling(current_idx); // now set it to -1, it will get a new one on next loop current_idx = -1; // now we check to see if we need to roll over into a new // file, this has to be in sync with the writer thread!! logger_buffers_written++; if ( logger_buffers_written > MAX_BUFFERS_PER_FILE ) { logger_buffers_written = 0; // we've hit the file size limit, restart counters flush_counters(); } } } chThdSleepMilliseconds(1); } return; }