auto-sync

This commit is contained in:
rusEfi 2014-11-16 18:03:30 -06:00
parent e56378380b
commit 83c05d0f19
1 changed files with 53 additions and 18 deletions

View File

@ -46,16 +46,33 @@
// we use this magic constant to make sure it's not just a random non-zero int in memory // we use this magic constant to make sure it's not just a random non-zero int in memory
#define MAGIC_LOGGING_FLAG 45234441 #define MAGIC_LOGGING_FLAG 45234441
typedef char log_buf_t[DL_OUTPUT_BUFFER];
/**
* we need to leave a byte for zero terminator, also two bytes for the \r\n in
* printWithLength, also couple of bytes just in case
*/
#define MAX_DL_CAPACITY (DL_OUTPUT_BUFFER - 5)
static log_buf_t pendingBuffers0 CCM_OPTIONAL
;
static log_buf_t pendingBuffers1
;
/** /**
* This is the buffer into which all the data providers write * This is the buffer into which all the data providers write
*/ */
static char pendingBuffer[DL_OUTPUT_BUFFER] CCM_OPTIONAL static char *accumulationBuffer;
;
/**
* amount of data accumulated so far
*/
static uint32_t accumulatedSize;
/** /**
* We copy all the pending data into this buffer once we are ready to push it out * We copy all the pending data into this buffer once we are ready to push it out
*/ */
static char outputBuffer[DL_OUTPUT_BUFFER]; static char * outputBuffer;
static MemoryStream intermediateLoggingBuffer; static MemoryStream intermediateLoggingBuffer;
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL
@ -87,6 +104,9 @@ void append(Logging *logging, const char *text) {
return; return;
} }
strcpy(logging->linePointer, text); strcpy(logging->linePointer, text);
/**
* And now we are pointing at the zero char at the end of the buffer again
*/
logging->linePointer += extraLen; logging->linePointer += extraLen;
} }
@ -313,6 +333,7 @@ void resetLogging(Logging *logging) {
return; return;
} }
logging->linePointer = buffer; logging->linePointer = buffer;
logging->linePointer[0] = 0;
} }
/** /**
@ -363,25 +384,19 @@ void scheduleLogging(Logging *logging) {
int newLength = efiStrlen(logging->buffer); int newLength = efiStrlen(logging->buffer);
bool alreadyLocked = lockOutputBuffer(); bool alreadyLocked = lockOutputBuffer();
// I hope this is fast enough to operate under sys lock if (accumulatedSize + newLength >= MAX_DL_CAPACITY) {
int curLength = efiStrlen(pendingBuffer);
if (curLength + newLength >= DL_OUTPUT_BUFFER) {
/** /**
* if no one is consuming the data we have to drop it * if no one is consuming the data we have to drop it
* this happens in case of serial-over-USB, todo: find a better solution * this happens in case of serial-over-USB, todo: find a better solution?
*
*/ */
// strcpy(fatalMessage, "datalogging.c: output buffer overflow: ");
// strcat(fatalMessage, logging->name);
// fatal(fatalMessage);
if (!alreadyLocked) { if (!alreadyLocked) {
unlockOutputBuffer(); unlockOutputBuffer();
} }
resetLogging(logging); resetLogging(logging);
return; return;
} }
strcpy(accumulationBuffer + accumulatedSize, logging->buffer);
strcat(pendingBuffer, logging->buffer); accumulatedSize += newLength;
if (!alreadyLocked) { if (!alreadyLocked) {
unlockOutputBuffer(); unlockOutputBuffer();
} }
@ -393,21 +408,41 @@ uint32_t remainingSize(Logging *logging) {
} }
/** /**
* This method actually sends all the pending data to the communication layer * This method actually sends all the pending data to the communication layer.
* This method is invoked by the main thread - that's the only thread which should be sending
* actual data to console in order to avoid concurrent access to serial hardware.
*/ */
void printPending(void) { void printPending(void) {
lockOutputBuffer(); lockOutputBuffer();
// we cannot output under syslock, so another buffer /**
strcpy(outputBuffer, pendingBuffer); * we cannot output under syslock, we simply rotate which buffer is which
pendingBuffer[0] = 0; // reset pending buffer */
char *temp = outputBuffer;
int expectedOutputSize = accumulatedSize;
outputBuffer = accumulationBuffer;
accumulationBuffer = temp;
accumulatedSize = 0;
accumulationBuffer[0] = 0;
unlockOutputBuffer(); unlockOutputBuffer();
if (efiStrlen(outputBuffer) > 0) { int actualOutputBuffer = efiStrlen(outputBuffer);
efiAssertVoid(actualOutputBuffer == expectedOutputSize, "out constr");
if (actualOutputBuffer > 0) {
printWithLength(outputBuffer); printWithLength(outputBuffer);
} }
} }
void initIntermediateLoggingBuffer(void) { void initIntermediateLoggingBuffer(void) {
pendingBuffers0[0] = 0;
pendingBuffers1[0] = 0;
accumulationBuffer = pendingBuffers0;
outputBuffer = pendingBuffers1;
accumulatedSize = 0;
msObjectInit(&intermediateLoggingBuffer, intermediateLoggingBufferData, INTERMEDIATE_LOGGING_BUFFER_SIZE, 0); msObjectInit(&intermediateLoggingBuffer, intermediateLoggingBufferData, INTERMEDIATE_LOGGING_BUFFER_SIZE, 0);
intermediateLoggingBufferInited = TRUE; intermediateLoggingBufferInited = TRUE;
} }