feat: Implement perf window

main
Sean McBride 4 years ago
parent 628275f6f9
commit c307f2a166

@ -5,6 +5,7 @@
#include "http.h"
#include "panic.h"
#include "perf_window.h"
#include "software_interrupt.h"
#include "types.h"
@ -37,6 +38,7 @@ struct module {
struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE];
struct sockaddr_in socket_address;
int socket_descriptor;
struct perf_window perf_window;
int port;
/*

@ -0,0 +1,96 @@
#pragma once
#include <spinlock/fas.h>
#include <stdint.h>
#define PERF_WINDOW_BUFFER_SIZE 10
struct perf_window {
uint64_t buffer[PERF_WINDOW_BUFFER_SIZE];
uint64_t count;
ck_spinlock_fas_t lock;
double mean;
};
/**
* Iterates through the values in the buffer and updates the mean
* Not intended to be called directly!
* @param self
*/
static inline void
perf_window_update_mean(struct perf_window *self)
{
assert(self != NULL);
assert(ck_spinlock_fas_locked(&self->lock));
uint64_t limit = self->count;
if (limit > PERF_WINDOW_BUFFER_SIZE) { limit = PERF_WINDOW_BUFFER_SIZE; }
uint64_t sum = 0;
for (uint64_t i = 0; i < limit; i++) sum += self->buffer[i];
self->mean = (double)(sum) / limit;
};
/**
* Iterates through the values in the buffer and updates the mean
* Not intended to be called directly!
* @param self
*/
static inline void
perf_window_initialize(struct perf_window *self)
{
assert(self != NULL);
ck_spinlock_fas_init(&self->lock);
self->count = 0;
self->mean = 0;
memset(&self->buffer, 0, sizeof(uint64_t) * PERF_WINDOW_BUFFER_SIZE);
}
/**
* Iterates through the values in the buffer and updates the mean
* Not intended to be called directly!
* @param self
* @param value
*/
static inline void
perf_window_add(struct perf_window *self, uint64_t value)
{
assert(self != NULL);
/* A successful invocation should run for a non-zero amount of time */
assert(value > 0);
ck_spinlock_fas_lock(&self->lock);
self->buffer[self->count++ % PERF_WINDOW_BUFFER_SIZE] = value;
perf_window_update_mean(self);
ck_spinlock_fas_unlock(&self->lock);
}
/**
* Returns mean perf value across all executions
* @returns mean or -1 if buffer is empty
*/
static inline double
perf_window_get_mean(struct perf_window *self)
{
assert(self != NULL);
if (self->count == 0) return -1;
return self->mean;
}
/**
* Returns the total count of executions
* @returns total count
*/
static inline uint64_t
perf_window_get_count(struct perf_window *self)
{
assert(self != NULL);
return self->count;
}

@ -201,6 +201,9 @@ module_new(char *name, char *path, int32_t argument_count, uint32_t stack_size,
/* Add the module to the in-memory module DB */
module_database_add(module);
/* Initialize Perf Window */
perf_window_initialize(&module->perf_window);
/* Start listening for requests */
module_listen(module);

Loading…
Cancel
Save