Skip to content
Snippets Groups Projects
Commit 4b517559 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

A somewhat sensible way to record OOM

parent e8337d71
Branches
Tags
No related merge requests found
CFLAGS = -Wall -O2 -m32
#CFLAGS := $(CFLAGS) -DEB_USE_DYNAMIC # deterministic untill table overflow (default)
#CFLAGS := $(CFLAGS) -DEB_USE_STATIC=100 # fully deterministic
#CFLAGS := $(CFLAGS) -DEB_USE_STATIC=200 # fully deterministic
#CFLAGS := $(CFLAGS) -DEB_USE_MALLOC # non-deterministic
#CFLAGS := $(CFLAGS) -DDISABLE_SLAVE
#CFLAGS := $(CFLAGS) -DDISABLE_MASTER
......@@ -11,6 +11,7 @@ TARGET = etherbone.a
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
SOURCES = memory/static.c \
memory/dynamic.c \
memory/array.c \
memory/malloc.c \
glue/operation.c \
glue/cycle.c \
......
......@@ -2,17 +2,14 @@
#include <stdlib.h>
#include "../etherbone.h"
struct stop {
int done;
eb_data_t result;
};
static void set_stop(eb_user_data_t user, eb_status_t status) {
struct stop* stop = (struct stop*)user;
stop->done = 1;
static void set_stop(eb_user_data_t user, eb_operation_t op, eb_status_t status) {
int* stop = (int*)user;
*stop = 1;
if (status != EB_OK) {
fprintf(stdout, "%s\n", eb_status(status));
} else {
fprintf(stdout, "%016"EB_DATA_FMT".\n", stop->result);
fprintf(stdout, "%016"EB_DATA_FMT".\n", eb_operation_data(op));
}
}
......@@ -22,7 +19,7 @@ int main(int argc, const char** argv) {
eb_device_t device;
eb_network_address_t netaddress;
eb_address_t address;
struct stop stop;
int stop;
int timeout;
if (argc != 3) {
......@@ -43,19 +40,19 @@ int main(int argc, const char** argv) {
return 1;
}
stop.result = 0;
stop = 0;
fprintf(stdout, "Reading from device %s at %08"EB_ADDR_FMT": ", netaddress, address);
fflush(stdout);
eb_device_read(device, address, &stop.result, &stop, &set_stop);
eb_device_read(device, address, 0, &stop, &set_stop);
eb_device_flush(device);
timeout = 5000000; /* 5 seconds */
while (!stop.done && timeout > 0) {
while (!stop && timeout > 0) {
timeout -= eb_socket_block(socket, timeout);
eb_socket_poll(socket);
}
if (!stop.done) {
if (!stop) {
fprintf(stdout, "FAILURE!\n");
fprintf(stderr, "Read from %s/%08"EB_ADDR_FMT" timed out.\n", netaddress, address);
}
......
......@@ -305,8 +305,7 @@ void eb_cycle_read_config(eb_cycle_t cycle,
eb_data_t* data);
/* Perform a wishbone write phase.
* data is written to the current cursor on the remote device.
* If the device was read-only, the operation is discarded.
* The given address is written on the remote device.
*/
EB_PUBLIC
void eb_cycle_write(eb_cycle_t cycle,
......
......@@ -49,7 +49,7 @@ void eb_cycle_destroy(eb_cycle_t cyclep) {
eb_free_operation(i);
}
eb_free_cycle(cyclep);
cycle->first = i;
}
void eb_cycle_abort(eb_cycle_t cyclep) {
......@@ -61,6 +61,7 @@ void eb_cycle_abort(eb_cycle_t cyclep) {
--device->unready;
eb_cycle_destroy(cyclep);
eb_free_cycle(cyclep);
}
void eb_cycle_close_silently(eb_cycle_t cyclep) {
......@@ -108,14 +109,21 @@ static struct eb_operation* eb_cycle_doop(eb_cycle_t cyclep) {
struct eb_operation* op;
static struct eb_operation crap;
cycle = EB_CYCLE(cyclep);
if (cycle->first == cyclep) {
/* Already ran OOM on this cycle */
return &crap;
}
opp = eb_new_operation();
if (opp == EB_NULL) {
/* Memory overflow; remove cycle as a candidate and report failure on close */
/* !!! */
/* Record out-of-memory with a self-pointer */
eb_cycle_destroy(cyclep);
cycle->first = cyclep;
return &crap;
}
cycle = EB_CYCLE(cyclep);
op = EB_OPERATION(opp);
op->next = cycle->first;
......
......@@ -10,20 +10,18 @@
#include "../etherbone.h"
/* Things i'd like to know: ran OOM ?
*/
struct eb_cycle {
eb_callback_t callback;
eb_user_data_t user_data;
eb_operation_t first;
eb_operation_t first; /* if points to cycle, means OOM */
union {
eb_cycle_t next;
eb_device_t device;
};
};
/* Recursively free the operations */
/* Recursively free the operations. Does not free cycle. */
void eb_cycle_destroy(eb_cycle_t cycle);
#endif
......@@ -52,7 +52,7 @@ eb_status_t eb_socket_close(eb_socket_t socketp) {
struct eb_response* response;
struct eb_cycle* cycle;
eb_response_t tmp;
eb_handler_address_t i;
eb_handler_address_t i, next;
socket = EB_SOCKET(socketp);
if (socket->first_device != EB_NULL)
......@@ -68,9 +68,8 @@ eb_status_t eb_socket_close(eb_socket_t socketp) {
(*cycle->callback)(cycle->user_data, cycle->first, EB_FAIL);
/* Free associated memory */
eb_cycle_abort(response->cycle);
eb_cycle_destroy(response->cycle);
eb_free_cycle(response->cycle);
eb_free_response(tmp);
}
while ((tmp = socket->last_response) != EB_NULL) {
......@@ -82,15 +81,16 @@ eb_status_t eb_socket_close(eb_socket_t socketp) {
(*cycle->callback)(cycle->user_data, cycle->first, EB_FAIL);
/* Free associated memory */
eb_cycle_abort(response->cycle);
eb_cycle_destroy(response->cycle);
eb_free_cycle(response->cycle);
eb_free_response(tmp);
}
/* Flush handlers */
for (i = socket->first_handler; i != EB_NULL; i = handler->next) {
for (i = socket->first_handler; i != EB_NULL; i = next) {
handler = EB_HANDLER_ADDRESS(i);
next = handler->next;
eb_free_handler_callback(handler->callback);
eb_free_handler_address(i);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment