auto-sync

This commit is contained in:
rusEfi 2014-11-16 18:03:30 -06:00
parent 87fc3ca7ba
commit db21facb37
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
#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
*/
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
*/
static char outputBuffer[DL_OUTPUT_BUFFER];
static char * outputBuffer;
static MemoryStream intermediateLoggingBuffer;
static uint8_t intermediateLoggingBufferData[INTERMEDIATE_LOGGING_BUFFER_SIZE] CCM_OPTIONAL
@ -87,6 +104,9 @@ void append(Logging *logging, const char *text) {
return;
}
strcpy(logging->linePointer, text);
/**
* And now we are pointing at the zero char at the end of the buffer again
*/
logging->linePointer += extraLen;
}
@ -313,6 +333,7 @@ void resetLogging(Logging *logging) {
return;
}
logging->linePointer = buffer;
logging->linePointer[0] = 0;
}
/**
@ -363,25 +384,19 @@ void scheduleLogging(Logging *logging) {
int newLength = efiStrlen(logging->buffer);
bool alreadyLocked = lockOutputBuffer();
// I hope this is fast enough to operate under sys lock
int curLength = efiStrlen(pendingBuffer);
if (curLength + newLength >= DL_OUTPUT_BUFFER) {
if (accumulatedSize + newLength >= MAX_DL_CAPACITY) {
/**
* 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) {
unlockOutputBuffer();
}
resetLogging(logging);
return;
}
strcat(pendingBuffer, logging->buffer);
strcpy(accumulationBuffer + accumulatedSize, logging->buffer);
accumulatedSize += newLength;
if (!alreadyLocked) {
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) {
lockOutputBuffer();
// we cannot output under syslock, so another buffer
strcpy(outputBuffer, pendingBuffer);
pendingBuffer[0] = 0; // reset pending buffer
/**
* we cannot output under syslock, we simply rotate which buffer is which
*/
char *temp = outputBuffer;
int expectedOutputSize = accumulatedSize;
outputBuffer = accumulationBuffer;
accumulationBuffer = temp;
accumulatedSize = 0;
accumulationBuffer[0] = 0;
unlockOutputBuffer();
if (efiStrlen(outputBuffer) > 0) {
int actualOutputBuffer = efiStrlen(outputBuffer);
efiAssertVoid(actualOutputBuffer == expectedOutputSize, "out constr");
if (actualOutputBuffer > 0) {
printWithLength(outputBuffer);
}
}
void initIntermediateLoggingBuffer(void) {
pendingBuffers0[0] = 0;
pendingBuffers1[0] = 0;
accumulationBuffer = pendingBuffers0;
outputBuffer = pendingBuffers1;
accumulatedSize = 0;
msObjectInit(&intermediateLoggingBuffer, intermediateLoggingBufferData, INTERMEDIATE_LOGGING_BUFFER_SIZE, 0);
intermediateLoggingBufferInited = TRUE;
}