summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/capture/capture_buffer.c
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-08-30 16:46:25 +1000
committerChris Johns <chrisj@rtems.org>2016-09-01 11:11:22 +1000
commit6da06c559f17f33177f59c0f83164bb2d20c8b9f (patch)
tree9f4b23a8f6e5215489ffbb8219c85fd11aa08e6c /cpukit/libmisc/capture/capture_buffer.c
parentarm/xilinx_zynq: Start the second core when an SMP build. (diff)
downloadrtems-6da06c559f17f33177f59c0f83164bb2d20c8b9f.tar.bz2
libmisc/capture: Fix the capture engine on SMP.
This patches some issues with the capture engine: 1. Check is the engine is open in ctrace commands. 2. Check all record open and appends for overflow. 3. Fix the record open to take the size of user data and not the record header. 4. Use packed structs for data being written to the per cpu buffers. 5. Remove direct struct access to the capture buffers to avoid misaligned accesses. 6. Add support to extract records, no struct access to the capture buffers. 7. Update ctrace to extract records from the capture buffers. 8. Add support to ctrace to always print the task name if it has one. 9. Add support to manage names or the lack of a name. 10. Range of minor fixes. 11. Fix a long standing bug in ctset's handling of args. Closes #2780.
Diffstat (limited to 'cpukit/libmisc/capture/capture_buffer.c')
-rw-r--r--cpukit/libmisc/capture/capture_buffer.c164
1 files changed, 88 insertions, 76 deletions
diff --git a/cpukit/libmisc/capture/capture_buffer.c b/cpukit/libmisc/capture/capture_buffer.c
index 13e6d1b624..be812b0af6 100644
--- a/cpukit/libmisc/capture/capture_buffer.c
+++ b/cpukit/libmisc/capture/capture_buffer.c
@@ -26,92 +26,104 @@
#include <rtems/score/assert.h>
#include "capture_buffer.h"
-void * rtems_capture_buffer_allocate( rtems_capture_buffer_t* buffer, size_t size )
+void*
+rtems_capture_buffer_allocate (rtems_capture_buffer_t* buffer, size_t size)
{
- size_t end;
- void *ptr;
-
- if ( rtems_capture_buffer_is_full( buffer ) )
- return NULL;
-
- if ( (buffer->count + size) > buffer->end )
- return NULL;
-
- /*
- * Determine if the end of free space is marked with
- * the end of buffer space, or the head of allocated
- * space.
- *
- * |...|head| freespace |tail| ...| end
- *
- * tail|.....|head| freespace| end
- *
- */
- if (buffer->tail > buffer->head) {
- end = buffer->tail;
- } else {
- end = buffer->end;
- }
+ void* ptr = NULL;
+
+ if ((buffer->count + size) <= buffer->end)
+ {
+ size_t end;
+
+ /*
+ * Determine if the end of free space is marked with the end of buffer
+ * space, or the head of allocated space.
+ *
+ * |...|head| freespace |tail| ...| end
+ *
+ * tail|.....|head| freespace| end
+ */
+ if (buffer->tail > buffer->head)
+ {
+ end = buffer->tail;
+ } else
+ {
+ end = buffer->end;
+ }
- /*
- * Can we allocate it easily?
- */
- if ((buffer->head + size) <= end) {
- ptr = &buffer->buffer[ buffer->head ];
- buffer->head += size;
- buffer->count = buffer->count + size;
- return ptr;
+ /*
+ * Can we allocate it easily?
+ */
+ if ((buffer->head + size) <= end)
+ {
+ ptr = &buffer->buffer[buffer->head];
+ buffer->head += size;
+ buffer->count = buffer->count + size;
+ if (buffer->max_rec < size)
+ buffer->max_rec = size;
+ }
+ else
+ {
+ /*
+ * We have to consider wrapping around to the front of the buffer
+ *
+ * If there is no room at the end of the buffer and we have we already
+ * wrapped then we can't allocate and if there is room at the front of
+ * the buffer.
+ */
+ if ((end != buffer->tail) && (buffer->tail >= size))
+ {
+ /*
+ * Change the end pointer to the last used byte, so a read will wrap
+ * when out of data
+ */
+ buffer->end = buffer->head;
+
+ /*
+ * Now return the buffer
+ */
+ ptr = buffer->buffer;
+ buffer->head = size;
+ buffer->count = buffer->count + size;
+ if (buffer->max_rec < size)
+ buffer->max_rec = size;
+ }
+ }
}
- /*
- * We have to consider wrapping around to the front of the buffer
- */
-
- /* If there is not room at the end of the buffer */
- /* and we have we already wrapped then we can't allocate */
- if ( end == buffer->tail )
- return NULL;
-
- /* Is there no room at the front of the buffer */
- if ( (buffer->tail < size ))
- return NULL;
-
- /* change the end pointer to the last used byte, so a read will wrap when out of data */
- buffer->end = buffer->head;
-
- /* now return the buffer */
- ptr = buffer->buffer;
- buffer->head = size;
- buffer->count = buffer->count + size;
-
return ptr;
}
-void *rtems_capture_buffer_free( rtems_capture_buffer_t* buffer, size_t size )
+void*
+rtems_capture_buffer_free (rtems_capture_buffer_t* buffer, size_t size)
{
- void *ptr;
- size_t next;
- size_t buff_size;
-
- if (size == 0)
- return NULL;
-
- ptr = rtems_capture_buffer_peek(buffer, &buff_size);
- next = buffer->tail + size;
+ void *ptr;
+ size_t next;
+ size_t buff_size;
- /* Check if we are freeing space past the end of the buffer */
- _Assert( ! rtems_capture_buffer_is_empty( buffer ) );
- _Assert( !((buffer->tail > buffer->head) && (next > buffer->end)) );
- _Assert( !((buffer->tail < buffer->head) && (next > buffer->head)) );
+ if (size == 0)
+ return NULL;
- buffer->count = buffer->count - size;
+ ptr = rtems_capture_buffer_peek (buffer, &buff_size);
+ next = buffer->tail + size;
- if (next == buffer->end) {
- buffer->end = buffer->size;
- buffer->tail = 0;
- } else {
- buffer->tail = next;
- }
+ /*
+ * Check if we are freeing space past the end of the buffer
+ */
+ _Assert (! rtems_capture_buffer_is_empty( buffer));
+ _Assert (!((buffer->tail > buffer->head) && (next > buffer->end)));
+ _Assert (!((buffer->tail < buffer->head) && (next > buffer->head)));
+
+ buffer->count = buffer->count - size;
+
+ if (next == buffer->end)
+ {
+ buffer->end = buffer->size;
+ buffer->tail = 0;
+ } else
+ {
+ buffer->tail = next;
+ }
- return ptr;
+ return ptr;
}