blob: 130521762f84e268a8205bc56de72668407cc0f1 [file] [log] [blame]
/*
* 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];
}
}