Commit d0a8fcc9 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Add busyloop trigger (very good timing on multicore systems)

Add controller_mem memory allocation functions.
All periodic data will be allocated in a continuous piece of memory hoping
for optimall cache behaviour with regards to associativity.
(TODO: really allocate continuous memory at the other side of the MMU)
parent 9f728334
...@@ -90,6 +90,18 @@ void log_send(enum log_type type, char *fmt, ...) ...@@ -90,6 +90,18 @@ void log_send(enum log_type type, char *fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
/* Unreliably try to see if going further makes sense */
msg = msgs_wr % LOG_MAX_QUEUE;
if (msgs[msg].used) {
/* Give up */
__sync_fetch_and_add(&lost_counter, 1);
sem_getvalue(&queue_wait, &val);
if (!val)
sem_post(&queue_wait);
return;
}
/* And now for real since it might work... */
msg = __sync_fetch_and_add(&msgs_wr, 1); msg = __sync_fetch_and_add(&msgs_wr, 1);
msg %= LOG_MAX_QUEUE; msg %= LOG_MAX_QUEUE;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <string.h> #include <string.h>
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_mem.h>
#include <log/log.h> #include <log/log.h>
/* /*
...@@ -74,7 +75,8 @@ static struct controller_block * block_decoder_uint32_bool_create(char *name, in ...@@ -74,7 +75,8 @@ static struct controller_block * block_decoder_uint32_bool_create(char *name, in
return NULL; return NULL;
dec->private->n = n; dec->private->n = n;
dec->private->out = calloc(sizeof(bool), n); dec->private->out = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_WRITE,
n, sizeof(bool));
if (!dec->private->out) if (!dec->private->out)
goto err_out; goto err_out;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_mem.h>
#include <block/block_filter_iir.h> #include <block/block_filter_iir.h>
#include <log/log.h> #include <log/log.h>
...@@ -96,11 +97,12 @@ static int param_set(struct controller_block *iir, int argc, va_list ap) ...@@ -96,11 +97,12 @@ static int param_set(struct controller_block *iir, int argc, va_list ap)
iir->private->param.zeros = zeros; iir->private->param.zeros = zeros;
if (iir->private->transfer) if (iir->private->transfer)
free(iir->private->transfer); controller_mem_free(iir->private->transfer);
iir->private->len = iir->private->param.len + 1; iir->private->len = iir->private->param.len + 1;
iir->private->transfer = malloc(sizeof(float[4]) * iir->private->transfer = controller_mem_calloc(
iir->private->len); CONTROLLER_MEM_PERIODIC_READ | CONTROLLER_MEM_PERIODIC_WRITE,
iir->private->len, sizeof(float[4]));
if (!iir->private->transfer) { if (!iir->private->transfer) {
iir->private->len = 0; iir->private->len = 0;
return -1; return -1;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_bus.h> #include <controller/controller_bus.h>
#include <controller/controller_mem.h>
#include <log/log.h> #include <log/log.h>
#include <linux/joystick.h> #include <linux/joystick.h>
...@@ -140,10 +141,12 @@ static struct controller_block * block_joystick_create(char *name, int argc, va_ ...@@ -140,10 +141,12 @@ static struct controller_block * block_joystick_create(char *name, int argc, va_
if (!(block = controller_block_alloc("joystick", name, sizeof(struct controller_block_private)))) if (!(block = controller_block_alloc("joystick", name, sizeof(struct controller_block_private))))
goto err_block; goto err_block;
block->private->axes = calloc(sizeof(float), nr_axes); block->private->axes = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_WRITE,
nr_axes, sizeof(float));
if (!block->private->axes) if (!block->private->axes)
goto err_axes; goto err_axes;
block->private->buttons = calloc(sizeof(bool), nr_buttons); block->private->buttons = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_WRITE,
nr_buttons, sizeof(bool));
if (!block->private->buttons) if (!block->private->buttons)
goto err_buttons; goto err_buttons;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <string.h> #include <string.h>
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_mem.h>
#include <log/log.h> #include <log/log.h>
/* /*
...@@ -80,7 +81,8 @@ static struct controller_block * block_multiplexer_create(char *name, int argc, ...@@ -80,7 +81,8 @@ static struct controller_block * block_multiplexer_create(char *name, int argc,
mul->private->n = n - 1; mul->private->n = n - 1;
mul->private->out = 0.0; mul->private->out = 0.0;
mul->private->in = calloc(sizeof(float*), n); mul->private->in = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_READ,
n, sizeof(float*));
if (!mul->private->in) if (!mul->private->in)
goto err_in; goto err_in;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_mem.h>
#include <log/log.h> #include <log/log.h>
/* /*
...@@ -129,7 +130,7 @@ static void ensure_state(struct controller_block *sm, uint32_t state) ...@@ -129,7 +130,7 @@ static void ensure_state(struct controller_block *sm, uint32_t state)
memset(priv->state_table + priv->state_nr, 0, sizeof(struct state)); memset(priv->state_table + priv->state_nr, 0, sizeof(struct state));
priv->state_table[priv->state_nr].state = state; priv->state_table[priv->state_nr].state = state;
priv->state_table[priv->state_nr].out = priv->state_table[priv->state_nr].out =
calloc(priv->no, sizeof(bool)); controller_mem_calloc(CONTROLLER_MEM_PERIODIC_READ, priv->no, sizeof(bool));
priv->state_nr++; priv->state_nr++;
} }
...@@ -179,8 +180,10 @@ static void add_transition(struct controller_block *sm, ...@@ -179,8 +180,10 @@ static void add_transition(struct controller_block *sm,
priv->state_table[statenr].transitions = realloc( priv->state_table[statenr].transitions = realloc(
priv->state_table[statenr].transitions, priv->state_table[statenr].transitions,
sizeof(struct transition) * (nr + 1)); sizeof(struct transition) * (nr + 1));
priv->state_table[statenr].transitions[nr].in = calloc(priv->ni, sizeof(bool)); priv->state_table[statenr].transitions[nr].in = controller_mem_calloc(
priv->state_table[statenr].transitions[nr].care = calloc(priv->ni, sizeof(bool)); CONTROLLER_MEM_PERIODIC_READ, priv->ni, sizeof(bool));
priv->state_table[statenr].transitions[nr].care = controller_mem_calloc(
CONTROLLER_MEM_PERIODIC_READ, priv->ni, sizeof(bool));
priv->state_table[statenr].transitions[nr].to = to_statenr; priv->state_table[statenr].transitions[nr].to = to_statenr;
for (i = 0; i < priv->ni; i++) { for (i = 0; i < priv->ni; i++) {
...@@ -255,11 +258,13 @@ static struct controller_block * block_state_machine_create(char *name, int argc ...@@ -255,11 +258,13 @@ static struct controller_block * block_state_machine_create(char *name, int argc
ensure_state(sm, 0); ensure_state(sm, 0);
sm->private->in = calloc(sizeof(bool*), ni); sm->private->in = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_READ,
ni, sizeof(bool*));
if (!sm->private->in) if (!sm->private->in)
goto err_in; goto err_in;
sm->private->out = calloc(sizeof(bool), no); sm->private->out = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_WRITE,
no, sizeof(bool));
if (!sm->private->out) if (!sm->private->out)
goto err_out; goto err_out;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_time.h> #include <controller/controller_time.h>
#include <controller/controller_mem.h>
#include <block/block_trajectplayer.h> #include <block/block_trajectplayer.h>
#include <log/log.h> #include <log/log.h>
...@@ -160,8 +161,9 @@ static int param_set_traject(struct controller_block *player, int argc, va_list ...@@ -160,8 +161,9 @@ static int param_set_traject(struct controller_block *player, int argc, va_list
priv->trajectories = realloc(priv->trajectories, priv->trajectories = realloc(priv->trajectories,
sizeof(struct block_trajectplayer_param *) * sizeof(struct block_trajectplayer_param *) *
priv->nr + 1); priv->nr + 1);
priv->trajectories[priv->nr] = calloc( priv->trajectories[priv->nr] = controller_mem_calloc(
sizeof(struct block_trajectplayer_param), 1); CONTROLLER_MEM_PERIODIC_READ, 1,
sizeof(struct block_trajectplayer_param));
priv->nr++; priv->nr++;
priv->trajectories[traject_nr]->nr = traject.nr; priv->trajectories[traject_nr]->nr = traject.nr;
} }
......
...@@ -7,6 +7,7 @@ CONTROLLER_SRCS= \ ...@@ -7,6 +7,7 @@ CONTROLLER_SRCS= \
$(DIR)/controller_block_trace.c \ $(DIR)/controller_block_trace.c \
$(DIR)/controller_bus.c \ $(DIR)/controller_bus.c \
$(DIR)/controller_command.c \ $(DIR)/controller_command.c \
$(DIR)/controller_mem.c \
$(DIR)/controller_time.c \ $(DIR)/controller_time.c \
$(DIR)/controller_trace.c \ $(DIR)/controller_trace.c \
$(DIR)/controller_sample.c \ $(DIR)/controller_sample.c \
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <pthread.h> #include <pthread.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <controller/controller_mem.h>
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_sample.h> #include <controller/controller_sample.h>
#include <controller/controller_bus.h> #include <controller/controller_bus.h>
...@@ -253,7 +254,6 @@ void controller_block_context_set(char *new_context) ...@@ -253,7 +254,6 @@ void controller_block_context_set(char *new_context)
int controller_block_sample_init(void) int controller_block_sample_init(void)
{ {
int i, j, k; int i, j, k;
void *tmp;
bool check = true; bool check = true;
/* Sanity check */ /* Sanity check */
...@@ -343,33 +343,25 @@ int controller_block_sample_init(void) ...@@ -343,33 +343,25 @@ int controller_block_sample_init(void)
calculates_sub = controller_time_subsample_get(); calculates_sub = controller_time_subsample_get();
calculates = calloc(sizeof(struct calculate_func *), calculates_sub); calculates = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_READ,
calculates_sub, sizeof(struct calculate_func *));
for (sub = 0; sub < calculates_sub; sub++) { for (sub = 0; sub < calculates_sub; sub++) {
int nr_calculates = 0; int nr_calculates = 0;
calculates[sub] = calloc(sizeof(struct calculate_func), 1);
for (i = 0; i < nr_blocks; i++) { for (i = 0; i < nr_blocks; i++) {
if (blocks[i]->calculate && controller_time_subsample_member(blocks[i]->time, sub)) { if (blocks[i]->calculate && controller_time_subsample_member(blocks[i]->time, sub)) {
// log_send(LOG_T_DEBUG, nr_calculates++;
// "Block %s has a calculate function", }
// blocks[i]->name); }
tmp = realloc(calculates[sub], calculates[sub] = controller_mem_calloc(
sizeof(struct calculate_func) * (nr_calculates+2)); CONTROLLER_MEM_PERIODIC_READ,
if (tmp) { nr_calculates + 1, sizeof(struct calculate_func));
calculates[sub] = tmp; j = 0;
calculates[sub][nr_calculates].func = for (i = 0; i < nr_blocks; i++) {
blocks[i]->calculate; if (blocks[i]->calculate && controller_time_subsample_member(blocks[i]->time, sub)) {
calculates[sub][nr_calculates].block = blocks[i]; calculates[sub][j].func = blocks[i]->calculate;
nr_calculates++; calculates[sub][j].block = blocks[i];
calculates[sub][nr_calculates].block = NULL; j++;
} else {
log_send(LOG_T_ERROR,
"Out of memory allocating memory");
}
} else {
// log_send(LOG_T_DEBUG,
// "Block %s has no calculate function",
// blocks[i]->name);
} }
} }
for (i = 0; i < sub; i++) { for (i = 0; i < sub; i++) {
...@@ -378,7 +370,7 @@ int controller_block_sample_init(void) ...@@ -378,7 +370,7 @@ int controller_block_sample_init(void)
!calculates[i][j].block) { !calculates[i][j].block) {
log_send(LOG_T_DEBUG, log_send(LOG_T_DEBUG,
"subsample %d is identical to subsample %d", sub, i); "subsample %d is identical to subsample %d", sub, i);
free(calculates[sub]); controller_mem_free(calculates[sub]);
calculates[sub] = calculates[i]; calculates[sub] = calculates[i];
i = sub; i = sub;
break; break;
...@@ -614,7 +606,8 @@ struct controller_block *controller_block_alloc(char *type, char *name, ...@@ -614,7 +606,8 @@ struct controller_block *controller_block_alloc(char *type, char *name,
{ {
struct controller_block *blk; struct controller_block *blk;
blk = calloc(1, sizeof(struct controller_block)); blk = controller_mem_calloc(CONTROLLER_MEM_PERIODIC_READ,
1, sizeof(struct controller_block));
if (!blk) if (!blk)
goto err_calloc; goto err_calloc;
...@@ -624,7 +617,10 @@ struct controller_block *controller_block_alloc(char *type, char *name, ...@@ -624,7 +617,10 @@ struct controller_block *controller_block_alloc(char *type, char *name,
goto err_name; goto err_name;
if (private_size > 0) { if (private_size > 0) {
blk->private = calloc(1, private_size); blk->private = controller_mem_calloc(
CONTROLLER_MEM_PERIODIC_WRITE |
CONTROLLER_MEM_PERIODIC_READ,
1, private_size);
if (!blk->private) if (!blk->private)
goto err_private; goto err_private;
} }
...@@ -636,11 +632,11 @@ struct controller_block *controller_block_alloc(char *type, char *name, ...@@ -636,11 +632,11 @@ struct controller_block *controller_block_alloc(char *type, char *name,
return blk; return blk;
err_time: err_time:
free(blk->private); controller_mem_free(blk->private);
err_private: err_private:
free(blk->name); free(blk->name);
err_name: err_name:
free(blk); controller_mem_free(blk);
err_calloc: err_calloc:
return NULL; return NULL;
} }
...@@ -650,12 +646,12 @@ void controller_block_free(struct controller_block *blk) ...@@ -650,12 +646,12 @@ void controller_block_free(struct controller_block *blk)
if (blk->name) if (blk->name)
free(blk->name); free(blk->name);
if (blk->private) if (blk->private)
free(blk->private); controller_mem_free(blk->private);
if (blk->input) if (blk->input)
free(blk->input); free(blk->input);
if (blk->output) if (blk->output)
free(blk->output); free(blk->output);
free(blk); controller_mem_free(blk);
} }
...@@ -123,7 +123,7 @@ int controller_block_param_list_add(struct controller_block *block, ...@@ -123,7 +123,7 @@ int controller_block_param_list_add(struct controller_block *block,
for (i = 0; list[i].name; i++) { for (i = 0; list[i].name; i++) {
for (j = 0; list[i].args[j]; j++); for (j = 0; list[i].args[j]; j++);
size_t argsize = sizeof(char *) * j; size_t argsize = sizeof(char *) * j;
entry = calloc(sizeof(struct controller_block_param_list) + argsize, 1); entry = calloc(1, sizeof(struct controller_block_param_list) + argsize);
if (!entry) if (!entry)
return 1; return 1;
entry->name = strdup(list[i].name); entry->name = strdup(list[i].name);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <controller/controller_block.h> #include <controller/controller_block.h>
#include <controller/controller_time.h> #include <controller/controller_time.h>
#include <controller/controller_mem.h>
#include <log/log.h> #include <log/log.h>
static int nr_traces = 0; static int nr_traces = 0;
...@@ -40,16 +41,11 @@ static struct controller_trace *trace_del_ptr = NULL; ...@@ -40,16 +41,11 @@ static struct controller_trace *trace_del_ptr = NULL;
void controller_block_trace_init(int max) void controller_block_trace_init(int max)
{ {
int i; traces = controller_mem_calloc(
CONTROLLER_MEM_PERIODIC_READ | CONTROLLER_MEM_PERIODIC_WRITE,
traces = malloc(sizeof(struct controller_trace *) * max); max, sizeof(struct controller_trace *));
max_traces = max; max_traces = max;
/* touch entire trace list */
for (i = 0; i < max; i++) {
traces[i] = NULL;
}
pthread_mutex_init(&trace_lock, NULL); pthread_mutex_init(&trace_lock, NULL);
sem_init(&trace_sync_sem, 0, 0); sem_init(&trace_sync_sem, 0, 0);
} }
......
...@@ -90,7 +90,7 @@ void controller_load_variable_alias_set(char *varname, char *block, char *term) ...@@ -90,7 +90,7 @@ void controller_load_variable_alias_set(char *varname, char *block, char *term)
} }
if (!entry) { if (!entry) {
entry = calloc(sizeof(struct variable), 1); entry = calloc(1, sizeof(struct variable));
entry->name = strdup(varname); entry->name = strdup(varname);
entry->next = variables; entry->next = variables;
...@@ -151,7 +151,7 @@ void controller_load_variable_double_set(char *varname, double val) ...@@ -151,7 +151,7 @@ void controller_load_variable_double_set(char *varname, double val)
} }
if (!entry) { if (!entry) {
entry = calloc(sizeof(struct variable), 1); entry = calloc(1, sizeof(struct variable));
entry->name = strdup(varname); entry->name = strdup(varname);
entry->next = variables; entry->next = variables;
...@@ -176,7 +176,7 @@ void controller_load_variable_int_set(char *varname, int val) ...@@ -176,7 +176,7 @@ void controller_load_variable_int_set(char *varname, int val)
} }
if (!entry) { if (!entry) {
entry = calloc(sizeof(struct variable), 1); entry = calloc(1, sizeof(struct variable));
entry->name = strdup(varname); entry->name = strdup(varname);
entry->next = variables; entry->next = variables;
...@@ -215,7 +215,7 @@ void controller_load_variable_string_set(char *varname, char *val) ...@@ -215,7 +215,7 @@ void controller_load_variable_string_set(char *varname, char *val)
} }
if (!entry) { if (!entry) {
entry = calloc(sizeof(struct variable), 1); entry = calloc(1, sizeof(struct variable));
entry->name = strdup(varname); entry->name = strdup(varname);
entry->next = variables; entry->next = variables;
......
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2015
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <controller/controller_mem.h>
#include <log/log.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
static size_t total;
static size_t total_w;
static size_t total_r;
#define BLOCK_SIZE (256*1024)
struct controller_mem_block {
struct controller_mem_block *next;
void *base;
struct controller_mem_chunk *chunks;
};
struct controller_mem_chunk {
struct controller_mem_chunk *next;
size_t off;
size_t len;
bool used;
};
static struct controller_mem_block *blocks;
static struct controller_mem_block *add_block(void)
{
struct controller_mem_block *block, **bptr;
block = calloc(1, sizeof(struct controller_mem_block));
if (!block)
goto err_block;
block->base = calloc(1, BLOCK_SIZE);
if (!block->base)
goto err_base;
block->chunks = calloc(1, sizeof(struct controller_mem_chunk));
if (!block->chunks)
goto err_chunk;
block->chunks->len = BLOCK_SIZE;
for (bptr = &blocks; *bptr; bptr = &((*bptr)->next));
*bptr = block;
return block;