355 |
355 |
356 /* Store one log message of give size */ |
356 /* Store one log message of give size */ |
357 int LogMessage(uint8_t level, char* buf, uint32_t size){ |
357 int LogMessage(uint8_t level, char* buf, uint32_t size){ |
358 if(size < LOG_BUFFER_SIZE - sizeof(mTail)){ |
358 if(size < LOG_BUFFER_SIZE - sizeof(mTail)){ |
359 uint32_t buffpos; |
359 uint32_t buffpos; |
|
360 uint64_t new_cursor, old_cursor; |
|
361 |
360 mTail tail; |
362 mTail tail; |
|
363 tail.msgsize = size; |
|
364 tail.tick = __tick; |
|
365 PLC_GetTime(&tail.time); |
|
366 |
361 /* We cannot increment both msg index and string pointer |
367 /* We cannot increment both msg index and string pointer |
362 in a single atomic operation but we can detect having been interrupted. |
368 in a single atomic operation but we can detect having been interrupted. |
363 So we can try with atomic compare and swap in a loop until operation |
369 So we can try with atomic compare and swap in a loop until operation |
364 succeeds non interrupted */ |
370 succeeds non interrupted */ |
365 uint64_t new_cursor, old_cursor; |
|
366 do{ |
371 do{ |
367 old_cursor = LogCursor[level]; |
372 old_cursor = LogCursor[level]; |
368 buffpos = (uint32_t)old_cursor; |
373 buffpos = (uint32_t)old_cursor; |
369 tail.msgidx = (old_cursor >> 32); |
374 tail.msgidx = (old_cursor >> 32); |
370 new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) |
375 new_cursor = ((uint64_t)(tail.msgidx + 1)<<32) |
371 | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK); |
376 | (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK); |
372 }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor)); |
377 }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor)); |
373 |
378 |
374 copy_to_log(level, buffpos, buf, size); |
379 copy_to_log(level, buffpos, buf, size); |
375 tail.msgsize = size; |
|
376 /*XXX tick*/ |
|
377 /*XXX RTC*/ |
|
378 copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail)); |
380 copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail)); |
379 |
381 |
380 return 1; /* Success */ |
382 return 1; /* Success */ |
381 }else{ |
383 }else{ |
382 char mstr[] = "Logging error : message too big"; |
384 char mstr[] = "Logging error : message too big"; |
388 uint32_t GetLogCount(uint8_t level){ |
390 uint32_t GetLogCount(uint8_t level){ |
389 return (uint64_t)LogCursor[level] >> 32; |
391 return (uint64_t)LogCursor[level] >> 32; |
390 } |
392 } |
391 |
393 |
392 /* Return message size and content */ |
394 /* Return message size and content */ |
393 uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size){ |
395 uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size, uint32_t* tick, uint32_t* tv_sec, uint32_t* tv_nsec){ |
394 uint64_t cursor = LogCursor[level]; |
396 uint64_t cursor = LogCursor[level]; |
395 if(cursor){ |
397 if(cursor){ |
396 /* seach cursor */ |
398 /* seach cursor */ |
397 uint32_t stailpos = (uint32_t)cursor; |
399 uint32_t stailpos = (uint32_t)cursor; |
398 uint32_t smsgidx; |
400 uint32_t smsgidx; |
407 copy_from_log(level, stailpos, &tail, sizeof(mTail)); |
409 copy_from_log(level, stailpos, &tail, sizeof(mTail)); |
408 }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx)); |
410 }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx)); |
409 |
411 |
410 if(tail.msgidx == msgidx){ |
412 if(tail.msgidx == msgidx){ |
411 uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; |
413 uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; |
412 uint32_t totalsize = tail.msgsize; /*sizeof(mTail);*/ |
414 uint32_t totalsize = tail.msgsize; |
413 copy_from_log(level, sbuffpos, buf, totalsize > max_size ? max_size : totalsize); |
415 *tick = tail.tick; |
|
416 *tv_sec = tail.time.tv_sec; |
|
417 *tv_nsec = tail.time.tv_nsec; |
|
418 copy_from_log(level, sbuffpos, buf, |
|
419 totalsize > max_size ? max_size : totalsize); |
414 return totalsize; |
420 return totalsize; |
415 } |
421 } |
416 } |
422 } |
417 return 0; |
423 return 0; |
418 } |
424 } |