| /* | |
| * Copyright 2017, Data61 | |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) | |
| * ABN 41 687 119 230. | |
| * | |
| * This software may be distributed and modified according to the terms of | |
| * the BSD 2-Clause license. Note that NO WARRANTY is provided. | |
| * See "LICENSE_BSD2.txt" for details. | |
| * | |
| * @TAG(DATA61_BSD) | |
| */ | |
| #include <sel4bench/logging.h> | |
| #include <stdlib.h> | |
| #include <malloc.h> | |
| #include <assert.h> | |
| void | |
| logging_init_log_buffer(log_buffer_t *log_buffer, unsigned int initial_capacity) | |
| { | |
| log_buffer->capacity = initial_capacity; | |
| log_buffer->length = 0; | |
| log_buffer->buffer = (seL4_Word*)malloc(initial_capacity * sizeof(seL4_Word)); | |
| log_buffer->full = 0; | |
| assert(log_buffer->buffer); | |
| } | |
| static void | |
| expand_log_buffer(log_buffer_t *log_buffer) | |
| { | |
| unsigned int new_capacity = log_buffer->capacity * 2; | |
| seL4_Word* new_buffer = (seL4_Word*)realloc(log_buffer->buffer, new_capacity * sizeof(seL4_Word)); | |
| if (new_buffer == NULL) { | |
| log_buffer->full = 1; | |
| } else { | |
| log_buffer->buffer = new_buffer; | |
| log_buffer->capacity = new_capacity; | |
| } | |
| } | |
| void | |
| logging_append_log_buffer(log_buffer_t *log_buffer, seL4_Word data) | |
| { | |
| if (log_buffer->length == log_buffer->capacity) { | |
| expand_log_buffer(log_buffer); | |
| } | |
| if (!log_buffer->full) { | |
| log_buffer->buffer[log_buffer->length] = data; | |
| ++log_buffer->length; | |
| } | |
| } | |
| void | |
| logging_separate_log(kernel_log_entry_t *logs, unsigned int num_logs, log_buffer_t *buffers, unsigned int num_buffers) | |
| { | |
| for (int i = 0; i < num_logs; ++i) { | |
| kernel_log_entry_t *entry = &logs[i]; | |
| seL4_Word key = kernel_logging_entry_get_key(entry); | |
| seL4_Word data = kernel_logging_entry_get_data(entry); | |
| if (key < num_buffers) { | |
| logging_append_log_buffer(&buffers[key], data); | |
| } | |
| } | |
| } | |
| static int | |
| log_compare(const void *a, const void *b) | |
| { | |
| return kernel_logging_entry_get_key((kernel_log_entry_t*)a) - | |
| kernel_logging_entry_get_key((kernel_log_entry_t*)b); | |
| } | |
| void | |
| logging_sort_log(kernel_log_entry_t *logs, unsigned int num_logs) | |
| { | |
| qsort(logs, num_logs, sizeof(kernel_log_entry_t), log_compare); | |
| } | |
| void | |
| logging_stable_sort_log(kernel_log_entry_t *logs, unsigned int num_logs) | |
| { | |
| /* Modify the keys so sorting preserves order within a single key */ | |
| for (int i = 0; i < num_logs; ++i) { | |
| kernel_log_entry_t *entry = &logs[i]; | |
| seL4_Word key = kernel_logging_entry_get_key(entry); | |
| key = key * num_logs + i; | |
| } | |
| logging_sort_log(logs, num_logs); | |
| /* Restore the original key values */ | |
| for (int i = 0; i < num_logs; ++i) { | |
| kernel_log_entry_t *entry = &logs[i]; | |
| seL4_Word key = kernel_logging_entry_get_key(entry); | |
| key = key / num_logs; | |
| } | |
| } | |
| void | |
| logging_group_log_by_key(kernel_log_entry_t *logs, unsigned int num_logs, | |
| unsigned int *sizes, unsigned int *offsets, | |
| unsigned int max_groups) | |
| { | |
| int index = 0; | |
| for (int i = 0; i < max_groups; ++i) { | |
| offsets[i] = index; | |
| while (index < num_logs && kernel_logging_entry_get_key(&logs[index]) == i) { | |
| ++index; | |
| } | |
| sizes[i] = index - offsets[i]; | |
| } | |
| } |