From 9ccd7d5f3c7b0597141e41a8f763d358b3198d0a Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 22 Oct 2012 15:19:31 +0800 Subject: refactor separate non aep specific stuff Signed-off-by: Andy Green --- aepd/main.c | 50 ++++++++++------- aepd/websocket-protocol.c | 10 ++-- arm-probe/arm-probe.c | 93 ++++++++++++++++++-------------- libarmep/Makefile.am | 6 ++- libarmep/aepd-interface.c | 104 +++++++++++++++++++++++++++++++++++ libarmep/aepd-interface.h | 73 +++++++++++++++++++++++++ libarmep/libarmep.h | 34 ++---------- libarmep/sample.c | 26 ++++----- libarmep/service.c | 135 ++++++++++++++-------------------------------- 9 files changed, 328 insertions(+), 203 deletions(-) create mode 100644 libarmep/aepd-interface.c create mode 100644 libarmep/aepd-interface.h diff --git a/aepd/main.c b/aepd/main.c index aacc79f..1be825b 100644 --- a/aepd/main.c +++ b/aepd/main.c @@ -28,6 +28,7 @@ unsigned long max_fifo_extent_seconds = 120; DOUBLES_PER_CH_SAMPLE * 10000 * max_fifo_extent_seconds) struct aepd_shared *aepd_shared; +struct aepd_interface *aepd_interface; static double sam[MAX_PROBES * CHANNELS_PER_PROBE * DOUBLES_PER_CH_SAMPLE]; extern struct libwebsocket_protocols protocols[]; @@ -113,7 +114,7 @@ int main(int argc, char *argv[]) int opts = 0; char interface_name[128] = ""; const char *interface_ptr = NULL; - struct aep_result *aep_result; + struct aepd_interface_result *aepd_interface_result; struct timeval tv; unsigned long last = 0; unsigned long ms10 = -1; @@ -193,6 +194,17 @@ int main(int argc, char *argv[]) } } + /* + * generic sample interface + */ + + aepd_interface = aepd_interface_create(); + if (aepd_interface == NULL) { + fprintf(stderr, "failed to create aepd_interface region\n"); + return -1; + } + aep_context.aepd_interface = aepd_interface; + /* libwebsockets context */ if (!use_ssl) @@ -210,7 +222,6 @@ int main(int argc, char *argv[]) configure(&aep_context, NULL, "/virtual", aep_context.config_filepath, NULL); - /* * fork off the AEP service process * runs in its own process to exploit SMP to dedicate one core for that @@ -253,18 +264,19 @@ int main(int argc, char *argv[]) } /* - * this process just has to deal with servicing AEP output from the - * AEP service process and making it available to the websocket - * services via the fifo ring file + * this process just has to deal with collecting samples from + * any backend that acquired them into the shared memory + * buffer, and then make them available to the websocket + * callback via the aepd private fifo ring file */ aepd_shared->chans = -1; while (loop) { - aep_result = aep_wait_for_next_result(&aep_context); - if (!aep_result) { - if (aep_context.aep_shared->finished) + aepd_interface_result = aep_wait_for_next_result(aep_context.aepd_interface); + if (!aepd_interface_result) { + if (aepd_interface->finished) loop = 0; continue; @@ -274,12 +286,12 @@ int main(int argc, char *argv[]) goto done; /* - * we have the next result in aep_result.. + * we have the next result in aepd_interface_result.. * voltage and current per channel */ m = 0; - for (n = 0; n < aep_result->chans * 2; n += 2) { + for (n = 0; n < aepd_interface_result->chans * 2; n += 2) { /* * accumulate in V, A, W per-channel. @@ -291,9 +303,9 @@ int main(int argc, char *argv[]) * Doubles are used to maximize dynamic range. */ - sam[m++] += aep_result->buf[n]; - sam[m++] += aep_result->buf[n + 1]; - sam[m++] += aep_result->buf[n] * aep_result->buf[n + 1]; + sam[m++] += aepd_interface_result->buf[n]; + sam[m++] += aepd_interface_result->buf[n + 1]; + sam[m++] += aepd_interface_result->buf[n] * aepd_interface_result->buf[n + 1]; } /* @@ -302,24 +314,24 @@ int main(int argc, char *argv[]) * is not at all the same as average V * average A */ - add_fifo(&sam[0], aep_result->chans * 3 * sizeof(double)); - aepd_shared->fifo_head_time = aep_result->samtime; + add_fifo(&sam[0], aepd_interface_result->chans * 3 * sizeof(double)); + aepd_shared->fifo_head_time = aepd_interface_result->samtime; - if (aepd_shared->chans != aep_result->chans) { - aepd_shared->chans = aep_result->chans; + if (aepd_shared->chans != aepd_interface_result->chans) { + aepd_shared->chans = aepd_interface_result->chans; zero_fifo(); } done: /* done with it */ - aep_free_result(&aep_context); + aep_free_result(aepd_interface); } close(aepd_shared->fd_fifo_write); close(aepd_shared->fd_fifo_read); unlink(aepd_shared->fifo_filepath); - sem_close(aep_context.semaphore); + aepd_interface_destroy(aepd_interface); fprintf(stderr, "exited\n"); diff --git a/aepd/websocket-protocol.c b/aepd/websocket-protocol.c index da965db..df9d96a 100644 --- a/aepd/websocket-protocol.c +++ b/aepd/websocket-protocol.c @@ -249,12 +249,12 @@ bad_caliper: /* signal it's a message with channel names */ *p++ = '='; - for (n = 0; n < aep_context.aep_shared->chans + aep_context.aep_shared->vchans; n++) + for (n = 0; n < aep_context.aepd_interface->chans + aep_context.aepd_interface->vchans; n++) p += sprintf(p, "%s,%s,%s,%s,;", - aep_context.aep_shared->channel_name[n], - aep_context.aep_shared->supply[n], - aep_context.aep_shared->colour[n], - aep_context.aep_shared->class[n]); + aep_context.aepd_interface->channel_name[n], + aep_context.aepd_interface->supply[n], + aep_context.aepd_interface->colour[n], + aep_context.aepd_interface->class[n]); pss->channels_sent_flag = 1; diff --git a/arm-probe/arm-probe.c b/arm-probe/arm-probe.c index 73eee51..fde030d 100644 --- a/arm-probe/arm-probe.c +++ b/arm-probe/arm-probe.c @@ -28,6 +28,8 @@ char stdinline[512] = ""; int stdinpos = 0; int stdinlen = 0; +struct aepd_interface *aepd_interface; + struct aep_context aep_context = { .config_filepath = "./config", .highest = -1, @@ -115,7 +117,7 @@ int main(int argc, char *argv[]) int m, i; int periodic = 0; double tt; - struct aep_result *aep_result; + struct aepd_interface_result *aepd_interface_result; int first = 1; loop = 1; @@ -278,6 +280,19 @@ int main(int argc, char *argv[]) } } + /* + * generic sample interface + */ + + aepd_interface = aepd_interface_create(); + if (aepd_interface == NULL) { + fprintf(stderr, "failed to create aepd_interface region\n"); + return -1; + } + aep_context.aepd_interface = aepd_interface; + + /* configure */ + configure(&aep_context, NULL, "/virtual", aep_context.config_filepath, NULL); /* @@ -318,9 +333,9 @@ int main(int argc, char *argv[]) while (loop) { - aep_result = aep_wait_for_next_result(&aep_context); - if (!aep_result) { - if (aep_context.aep_shared->finished) + aepd_interface_result = aep_wait_for_next_result(aepd_interface); + if (!aepd_interface_result) { + if (aepd_interface->finished) loop = 0; continue; @@ -328,55 +343,55 @@ int main(int argc, char *argv[]) if (first) { first = 0; - for (n = 0; n < aep_context.aep_shared->chans + aep_context.aep_shared->vchans; n++) + for (n = 0; n < aepd_interface->chans + aepd_interface->vchans; n++) printf("# %s\t%s\t%s\t%s\t%s\n", - aep_context.aep_shared->channel_name[n], - aep_context.aep_shared->channel_name_pretty[n], - aep_context.aep_shared->supply[n], - aep_context.aep_shared->colour[n], - aep_context.aep_shared->class[n]); + aepd_interface->channel_name[n], + aepd_interface->channel_name_pretty[n], + aepd_interface->supply[n], + aepd_interface->colour[n], + aepd_interface->class[n]); printf("#\n#\ntime "); - for (n = 0; n < aep_context.aep_shared->chans; n++) + for (n = 0; n < aepd_interface->chans; n++) if (just_power) - printf(" %s(W)", aep_context.aep_shared->channel_name_pretty[n]); + printf(" %s(W)", aepd_interface->channel_name_pretty[n]); else printf(" %s(V) %s(A) %s(W)", - aep_context.aep_shared->channel_name_pretty[n], - aep_context.aep_shared->channel_name_pretty[n], - aep_context.aep_shared->channel_name_pretty[n]); + aepd_interface->channel_name_pretty[n], + aepd_interface->channel_name_pretty[n], + aepd_interface->channel_name_pretty[n]); printf("\n"); } periodic++; if ((periodic & 0x1ff) == 0) { - if (aep_result->triggered) + if (aepd_interface_result->triggered) fprintf(stderr, "TRIGD "); else fprintf(stderr, "ARMED "); } - if (aep_result->triggered) - printf("%f ", aep_result->samtime); - for (i = 0; i < aep_result->chans * 2; i += 2) { - if (aep_result->triggered) { + if (aepd_interface_result->triggered) + printf("%f ", aepd_interface_result->samtime); + for (i = 0; i < aepd_interface_result->chans * 2; i += 2) { + if (aepd_interface_result->triggered) { if (just_power) - printf(" %.5f", aep_result->buf[i] * aep_result->buf[i + 1]); + printf(" %.5f", aepd_interface_result->buf[i] * aepd_interface_result->buf[i + 1]); else printf(" %.2f %.4f %.5f", - aep_result->buf[i], aep_result->buf[i + 1], aep_result->buf[i] * aep_result->buf[i + 1]); + aepd_interface_result->buf[i], aepd_interface_result->buf[i + 1], aepd_interface_result->buf[i] * aepd_interface_result->buf[i + 1]); } if (periodic & 0x1ff) continue; if (just_power) - fprintf(stderr, " %.5f", aep_result->buf[i] * aep_result->buf[i + 1]); + fprintf(stderr, " %.5f", aepd_interface_result->buf[i] * aepd_interface_result->buf[i + 1]); else fprintf(stderr, " %.2f %.4f %.5f", - aep_result->buf[i], aep_result->buf[i + 1], aep_result->buf[i] * aep_result->buf[i + 1]); + aepd_interface_result->buf[i], aepd_interface_result->buf[i + 1], aepd_interface_result->buf[i] * aepd_interface_result->buf[i + 1]); } - if (aep_result->triggered) + if (aepd_interface_result->triggered) printf("\n"); - aep_free_result(&aep_context); + aep_free_result(aepd_interface); if (periodic & 0x1ff) continue; @@ -384,7 +399,7 @@ int main(int argc, char *argv[]) } - aep_context.aep_shared->finished = 1; + aep_context.aepd_interface->finished = 1; /* * we are finished if we reach here... @@ -404,14 +419,14 @@ int main(int argc, char *argv[]) } else printf("%f", tt); - for (n = 0; n <= aep_context.aep_shared->chans; n++) { + for (n = 0; n <= aep_context.aepd_interface->chans; n++) { if (just_power) - printf(" %.5f", aep_context.aep_shared->averages[n][2]); + printf(" %.5f", aep_context.aepd_interface->averages[n][2]); else printf(" %.2f %.4f %.5f", - aep_context.aep_shared->averages[n][0], - aep_context.aep_shared->averages[n][1], - aep_context.aep_shared->averages[n][2]); + aep_context.aepd_interface->averages[n][0], + aep_context.aepd_interface->averages[n][1], + aep_context.aepd_interface->averages[n][2]); } printf("\n"); @@ -425,21 +440,21 @@ int main(int argc, char *argv[]) fprintf(stderr, "\n\n"); - for (n = 0; n < aep_context.aep_shared->chans; n++) { + for (n = 0; n < aepd_interface->chans; n++) { - if (aep_context.aep_shared->min[n][0] == 999) + if (aepd_interface->min[n][0] == 999) continue; fprintf(stderr, "%12s: %4.2fV < %4.3fVavg < %4.2fV, " "%6.4fA < %6.5fAavg < %6.4fA, " "%9.6fW < %9.6fWavg < %9.6fW\n", - aep_context.aep_shared->channel_name[n], - aep_context.aep_shared->min[n][0], aep_context.aep_shared->averages[n][0], aep_context.aep_shared->max[n][0], - aep_context.aep_shared->min[n][1], aep_context.aep_shared->averages[n][1], aep_context.aep_shared->max[n][1], - aep_context.aep_shared->min[n][2], aep_context.aep_shared->averages[n][2], aep_context.aep_shared->max[n][2]); + aepd_interface->channel_name[n], + aepd_interface->min[n][0], aepd_interface->averages[n][0], aepd_interface->max[n][0], + aepd_interface->min[n][1], aepd_interface->averages[n][1], aepd_interface->max[n][1], + aepd_interface->min[n][2], aepd_interface->averages[n][2], aepd_interface->max[n][2]); } - sem_close(aep_context.semaphore); + aepd_interface_destroy(aepd_interface); fprintf(stderr, "exited\n"); diff --git a/libarmep/Makefile.am b/libarmep/Makefile.am index e1ed7fc..79dc801 100644 --- a/libarmep/Makefile.am +++ b/libarmep/Makefile.am @@ -1,12 +1,14 @@ lib_LTLIBRARIES=libarmep.la -include_HEADERS=libarmep.h +include_HEADERS=libarmep.h aepd-interface.h dist_libarmep_la_SOURCES=sample.c \ interpolation.c \ configuration.c \ avg-mean-us.c \ protocol.c \ service.c \ - libarmep.h + aepd-interface.c \ + libarmep.h \ + aepd-interface.h libarmep_la_CFLAGS=-Wall -Werror -std=gnu99 -pedantic -pthread -D_FORTIFY_SOURCE=2 -fstack-protector libarmep_la_LDFLAGS=-pthread diff --git a/libarmep/aepd-interface.c b/libarmep/aepd-interface.c new file mode 100644 index 0000000..e78b308 --- /dev/null +++ b/libarmep/aepd-interface.c @@ -0,0 +1,104 @@ +/* + * Author: Andy Green + * Copyright (C) 2012 Linaro, LTD + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aepd-interface.h" + +struct aepd_interface *aepd_interface_create(void) +{ + struct aepd_interface *aepd_interface; + int n; + + /* + * create our lump of shared memory + * which is usable by all forked threads + */ + + n = open("/dev/zero", O_RDWR); + aepd_interface = mmap(NULL, sizeof (struct aepd_interface), + PROT_READ | PROT_WRITE, MAP_SHARED, n, 0); + close(n); + + aepd_interface->head = 0; + aepd_interface->tail = 0; + + sprintf(aepd_interface->semname, "linaro.aep.%u\n", getpid()); + + aepd_interface->semaphore = sem_open(aepd_interface->semname, O_CREAT | O_RDWR, 0600, 0); + if (aepd_interface->semaphore == SEM_FAILED) { + fprintf(stderr, "Failed to open sem %s\n", aepd_interface->semname); + return NULL; + } + + return aepd_interface; +} + +void aepd_interface_destroy(struct aepd_interface *aepd_interface) +{ + sem_close(aepd_interface->semaphore); + if (munmap(aepd_interface, sizeof (struct aepd_interface)) < 0) + fprintf(stderr, "munmap failed\n"); +} + +/* + * helper for user code to block until next aep_result available + */ + +struct aepd_interface_result * aep_wait_for_next_result(struct aepd_interface *aepd_interface) +{ + struct timespec ts; + struct timeval tv; + + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + 2; + ts.tv_nsec = 0; + + if (sem_timedwait(aepd_interface->semaphore, &ts) < 0) + return NULL; + + if (aepd_interface->tail == aepd_interface->head) + return NULL; + + return &aepd_interface->aepd_interface_result[aepd_interface->tail]; +} + +/* + * helper for user code to deal with ringbuffer + */ + +void aep_free_result(struct aepd_interface *aepd_interface) +{ + if (aepd_interface->tail == sizeof(aepd_interface->aepd_interface_result) / sizeof(aepd_interface->aepd_interface_result[0]) - 1) + aepd_interface->tail = 0; + else + aepd_interface->tail++; +} + diff --git a/libarmep/aepd-interface.h b/libarmep/aepd-interface.h new file mode 100644 index 0000000..9b43352 --- /dev/null +++ b/libarmep/aepd-interface.h @@ -0,0 +1,73 @@ +/* + * Author: Andy Green + * Copyright (C) 2012 Linaro, LTD + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * These are the interface structs between the acquisition-specific + * code and the shared memory buffers, which are just abstracted + * sample and channel descriptions with no knowledge of what + * produced them + */ + +#define AEPD_SHARED_MAX_REAL_CHANNELS (8 * 3) +#define AEPD_SHARED_MAX_VIRTUAL_CHANNELS (8) + +struct aepd_interface_result { + int triggered; /* 0 = pretrigger 1 = triggered */ + int chans; /* number of channels below with data */ + double samtime; /* sample time in s */ + + /* For each channel: { common-mode voltage in V, current in A } */ + double buf[AEPD_SHARED_MAX_REAL_CHANNELS * 2]; +}; + +struct aepd_interface { + + /* ringbuffer to hold channel_results until we can deal with them */ + + int head; + int tail; + struct aepd_interface_result aepd_interface_result[1000]; + + /* synchronization object signalling new result written */ + sem_t * semaphore; + char semname[64]; + + /* metadata about the channels */ + + char channel_name[AEPD_SHARED_MAX_VIRTUAL_CHANNELS + AEPD_SHARED_MAX_REAL_CHANNELS][64]; + char channel_name_pretty[AEPD_SHARED_MAX_VIRTUAL_CHANNELS + AEPD_SHARED_MAX_REAL_CHANNELS][64]; + char supply[AEPD_SHARED_MAX_VIRTUAL_CHANNELS + AEPD_SHARED_MAX_REAL_CHANNELS][64]; + char colour[AEPD_SHARED_MAX_VIRTUAL_CHANNELS + AEPD_SHARED_MAX_REAL_CHANNELS][16]; + char class[AEPD_SHARED_MAX_VIRTUAL_CHANNELS + AEPD_SHARED_MAX_REAL_CHANNELS][16]; + int chans; /* number of active acquisition channels above */ + int vchans; /* virtual channels (summing supplies) appear after probed physical channels in the arrays */ + int finished; /* are we going down? */ + + /* simple stats on what was captured */ + + double averages[AEPD_SHARED_MAX_REAL_CHANNELS][3]; + double min[AEPD_SHARED_MAX_REAL_CHANNELS][3]; + double max[AEPD_SHARED_MAX_REAL_CHANNELS][3]; + +}; + +extern struct aepd_interface *aepd_interface_create(void); +extern void aepd_interface_destroy(struct aepd_interface *aepd_interface); +extern struct aepd_interface_result * aep_wait_for_next_result(struct aepd_interface *aepd_interface); +extern void aep_free_result(struct aepd_interface *aepd_interface); + diff --git a/libarmep/libarmep.h b/libarmep/libarmep.h index 8811fce..2247b46 100644 --- a/libarmep/libarmep.h +++ b/libarmep/libarmep.h @@ -36,6 +36,8 @@ #include #include +#include "aepd-interface.h" + #define MAX_PROBES 8 #define CHANNELS_PER_PROBE 3 @@ -227,31 +229,6 @@ struct aep { struct aep_channel ch[CHANNELS_PER_PROBE]; }; -struct aep_result { - int triggered; - int chans; - double samtime; - double buf[MAX_PROBES * CHANNELS_PER_PROBE * 2]; - -}; - -struct aep_shared { - int head; - int tail; - struct aep_result aep_result[1000]; - char channel_name[MAX_VIRTUAL_CHANNELS + MAX_PROBES * CHANNELS_PER_PROBE][64]; - char channel_name_pretty[MAX_VIRTUAL_CHANNELS + MAX_PROBES * CHANNELS_PER_PROBE][64]; - char supply[MAX_VIRTUAL_CHANNELS + MAX_PROBES * CHANNELS_PER_PROBE][64]; - char colour[MAX_VIRTUAL_CHANNELS + MAX_PROBES * CHANNELS_PER_PROBE][16]; - char class[MAX_VIRTUAL_CHANNELS + MAX_PROBES * CHANNELS_PER_PROBE][16]; - int chans; - int vchans; /* appear after probed physical channels in the arrays*/ - int finished; - double averages[MAX_PROBES * CHANNELS_PER_PROBE][3]; - double min[MAX_PROBES * CHANNELS_PER_PROBE][3]; - double max[MAX_PROBES * CHANNELS_PER_PROBE][3]; - -}; struct aep_context { struct aep aeps[MAX_PROBES]; @@ -289,10 +266,9 @@ struct aep_context { int poll_timeout_ms; double do_average; - /* shared memory output buffer */ + /* shared memory output buffer + metadata */ - struct aep_shared *aep_shared; - sem_t * semaphore; + struct aepd_interface *aepd_interface; }; @@ -338,6 +314,4 @@ extern void init_interpolation(void); extern int service_aeps(struct aep_context *aep_context, int fd); extern int aep_init_and_fork(struct aep_context *aep_context, char *argv[]); -extern struct aep_result * aep_wait_for_next_result(struct aep_context *aep_context); -extern void aep_free_result(struct aep_context *aep_context); diff --git a/libarmep/sample.c b/libarmep/sample.c index f17a803..df6b278 100644 --- a/libarmep/sample.c +++ b/libarmep/sample.c @@ -90,8 +90,8 @@ int process_sample(struct aep *aep, int ch_index) struct aep_channel *ch = &aep->ch[ch_index], *ich; double v1, v2, v1a, v2a, vo0 = 0, vo1 = 0; int m, i, from_pretrig = 0, n, hit; - struct aep_shared *aep_shared; - struct aep_result *aep_result; + struct aepd_interface *aepd_interface; + struct aepd_interface_result *aepd_interface_result; if (!aep->aep_context->no_correction) { vo0 = ch->voffset[0]; @@ -302,12 +302,12 @@ unripe: /* if so, output it all together */ - aep_shared = aep->aep_context->aep_shared; - aep_result = &aep_shared->aep_result[aep_shared->head]; + aepd_interface = aep->aep_context->aepd_interface; + aepd_interface_result = &aepd_interface->aepd_interface_result[aepd_interface->head]; - aep_result->triggered = ch->triggered; - aep_result->chans = hit; - aep_result->samtime = ((double)ch->samples_seen - (double)ch->ring_samples) / 10000.0; + aepd_interface_result->triggered = ch->triggered; + aepd_interface_result->chans = hit; + aepd_interface_result->samtime = ((double)ch->samples_seen - (double)ch->ring_samples) / 10000.0; n = 0; @@ -332,17 +332,17 @@ unripe: if (!ich->requested) continue; - aep_result->buf[n++] = v1a; - aep_result->buf[n++] = v2a; + aepd_interface_result->buf[n++] = v1a; + aepd_interface_result->buf[n++] = v2a; } } - if (aep_shared->head == (sizeof(aep_shared->aep_result) / sizeof(aep_shared->aep_result[0])) - 1) - aep_shared->head = 0; + if (aepd_interface->head == (sizeof(aepd_interface->aepd_interface_result) / sizeof(aepd_interface->aepd_interface_result[0])) - 1) + aepd_interface->head = 0; else - aep_shared->head++; + aepd_interface->head++; - if (sem_post(aep->aep_context->semaphore) < 0) + if (sem_post(aep->aep_context->aepd_interface->semaphore) < 0) fprintf(stderr, "failed to set semaphore\n"); done: diff --git a/libarmep/service.c b/libarmep/service.c index 68a7028..d6d40b0 100644 --- a/libarmep/service.c +++ b/libarmep/service.c @@ -21,7 +21,6 @@ #include "libarmep.h" #include -#include void add_pollfd(struct aep_context *aep_context, int fd, int events) { @@ -150,18 +149,18 @@ void probe_close(struct aep *aep) close(aep->fd); } -static void copy_public_ch_info_to_shared(struct aep_shared *aep_shared, int chan, struct aep_channel *ch) +static void copy_public_ch_info_to_shared(struct aepd_interface *aepd_interface, int chan, struct aep_channel *ch) { - strncpy(aep_shared->channel_name[chan], ch->channel_name, sizeof(aep_shared->channel_name[0])); - aep_shared->channel_name[chan][sizeof(aep_shared->channel_name[0]) - 1] = '\0'; - strncpy(aep_shared->channel_name_pretty[chan], ch->channel_name_pretty, sizeof(aep_shared->channel_name_pretty[0])); - aep_shared->channel_name_pretty[chan][sizeof(aep_shared->channel_name_pretty[0]) - 1] = '\0'; - strncpy(aep_shared->supply[chan], ch->supply, sizeof(aep_shared->supply[0])); - aep_shared->supply[chan][sizeof(aep_shared->supply[0]) - 1] = '\0'; - strncpy(aep_shared->colour[chan], ch->colour, sizeof(aep_shared->colour[0])); - aep_shared->colour[chan][sizeof(aep_shared->colour[0]) - 1] = '\0'; - strncpy(aep_shared->class[chan], ch->class, sizeof(aep_shared->class[0])); - aep_shared->class[chan][sizeof(aep_shared->class[0]) - 1] = '\0'; + strncpy(aepd_interface->channel_name[chan], ch->channel_name, sizeof(aepd_interface->channel_name[0])); + aepd_interface->channel_name[chan][sizeof(aepd_interface->channel_name[0]) - 1] = '\0'; + strncpy(aepd_interface->channel_name_pretty[chan], ch->channel_name_pretty, sizeof(aepd_interface->channel_name_pretty[0])); + aepd_interface->channel_name_pretty[chan][sizeof(aepd_interface->channel_name_pretty[0]) - 1] = '\0'; + strncpy(aepd_interface->supply[chan], ch->supply, sizeof(aepd_interface->supply[0])); + aepd_interface->supply[chan][sizeof(aepd_interface->supply[0]) - 1] = '\0'; + strncpy(aepd_interface->colour[chan], ch->colour, sizeof(aepd_interface->colour[0])); + aepd_interface->colour[chan][sizeof(aepd_interface->colour[0]) - 1] = '\0'; + strncpy(aepd_interface->class[chan], ch->class, sizeof(aepd_interface->class[0])); + aepd_interface->class[chan][sizeof(aepd_interface->class[0]) - 1] = '\0'; } @@ -374,10 +373,10 @@ bail: if (!ch->requested) continue; - copy_public_ch_info_to_shared(aep_context->aep_shared, chan, ch); + copy_public_ch_info_to_shared(aep_context->aepd_interface, chan, ch); chan++; - aep_context->aep_shared->chans = chan; + aep_context->aepd_interface->chans = chan; } aep_context->aeps[m].started = 1; @@ -386,8 +385,8 @@ bail: } for (m = 0; m < aep_context->count_virtual_channels; m++) { - copy_public_ch_info_to_shared(aep_context->aep_shared, chan++, &aep_context->vch[m]); - aep_context->aep_shared->vchans++; + copy_public_ch_info_to_shared(aep_context->aepd_interface, chan++, &aep_context->vch[m]); + aep_context->aepd_interface->vchans++; } } @@ -530,7 +529,7 @@ service: if (aep_context->scans > (5 * MAX_PROBES) && aep_context->awaiting_capture == 0 && aep_context->exit_after_capture) { fprintf(stderr, "done all capture\n"); - aep_context->aep_shared->finished = 1; + aep_context->aepd_interface->finished = 1; return -1; } @@ -556,37 +555,21 @@ void sighandler(int sig) } +/* + * you should have called aepd_interface_create() above + * and set aep_context->aepd_interface to the result + * before calling this + */ + int aep_init_and_fork(struct aep_context *aep_context, char *argv[]) { int n, m, i; struct aep_channel *ch; - char semname[64]; loop = 1; init_interpolation(); - /* - * create our lump of shared memory - * which is usable by all forked threads - */ - - n = open("/dev/zero", O_RDWR); - aep_context->aep_shared = mmap(NULL, sizeof (struct aep_shared), - PROT_READ | PROT_WRITE, MAP_SHARED, n, 0); - close(n); - - aep_context->aep_shared->head = 0; - aep_context->aep_shared->tail = 0; - - sprintf(semname, "linaro.aep.%u\n", getpid()); - - aep_context->semaphore = sem_open(semname, O_CREAT | O_RDWR, 0600, 0); - if (aep_context->semaphore == SEM_FAILED) { - fprintf(stderr, "Failed to open sem %s\n", semname); - return -1; - } - /* fork off aep service loop */ n = fork(); @@ -603,31 +586,31 @@ int aep_init_and_fork(struct aep_context *aep_context, char *argv[]) if (argv) strcpy(argv[0] + strlen(argv[0]), " - AEP server"); - aep_context->semaphore = sem_open(semname, O_RDWR, 0600, 0); - if (aep_context->semaphore == SEM_FAILED) { - fprintf(stderr, "Child failed to open sem %s\n", semname); + aep_context->aepd_interface->semaphore = sem_open(aep_context->aepd_interface->semname, O_RDWR, 0600, 0); + if (aep_context->aepd_interface->semaphore == SEM_FAILED) { + fprintf(stderr, "Child failed to open sem %s\n", aep_context->aepd_interface->semname); return -1; } - aep_context->aep_shared->finished = 0; + aep_context->aepd_interface->finished = 0; aep_context->poll_timeout_ms = 10; - while (!aep_context->aep_shared->finished && loop && getppid() != 1) { + while (!aep_context->aepd_interface->finished && loop && getppid() != 1) { n = poll(aep_context->pollfds, aep_context->count_pollfds, aep_context->poll_timeout_ms); if (n < 0) - aep_context->aep_shared->finished = 1; + aep_context->aepd_interface->finished = 1; for (n = 0; n < aep_context->count_pollfds; n++) if (aep_context->pollfds[n].revents) if (service_aeps(aep_context, aep_context->pollfds[n].fd) < 0) - aep_context->aep_shared->finished = 1; + aep_context->aepd_interface->finished = 1; if (service_aeps(aep_context, -1) < 0) - aep_context->aep_shared->finished = 1; + aep_context->aepd_interface->finished = 1; } - sem_close(aep_context->semaphore); + sem_close(aep_context->aepd_interface->semaphore); /* * Compute and stash the averages @@ -645,15 +628,15 @@ int aep_init_and_fork(struct aep_context *aep_context, char *argv[]) aep_context->config_filepath, ch) < 0) fprintf(stderr, "failed to update config\n"); - aep_context->aep_shared->averages[m][0] = ch->simple_avg[0] / ch->avg_count; - aep_context->aep_shared->averages[m][1] = ch->simple_avg[1] / ch->avg_count; - aep_context->aep_shared->averages[m][2] = ch->simple_avg[2] / ch->avg_count; - aep_context->aep_shared->min[m][0] = ch->min[0]; - aep_context->aep_shared->min[m][1] = ch->min[1]; - aep_context->aep_shared->min[m][2] = ch->min[2]; - aep_context->aep_shared->max[m][0] = ch->max[0]; - aep_context->aep_shared->max[m][1] = ch->max[1]; - aep_context->aep_shared->max[m][2] = ch->max[2]; + aep_context->aepd_interface->averages[m][0] = ch->simple_avg[0] / ch->avg_count; + aep_context->aepd_interface->averages[m][1] = ch->simple_avg[1] / ch->avg_count; + aep_context->aepd_interface->averages[m][2] = ch->simple_avg[2] / ch->avg_count; + aep_context->aepd_interface->min[m][0] = ch->min[0]; + aep_context->aepd_interface->min[m][1] = ch->min[1]; + aep_context->aepd_interface->min[m][2] = ch->min[2]; + aep_context->aepd_interface->max[m][0] = ch->max[0]; + aep_context->aepd_interface->max[m][1] = ch->max[1]; + aep_context->aepd_interface->max[m][2] = ch->max[2]; m++; } @@ -663,43 +646,5 @@ int aep_init_and_fork(struct aep_context *aep_context, char *argv[]) return 0; } -/* - * helper for user code to block until next aep_result available - */ - -struct aep_result * aep_wait_for_next_result(struct aep_context *aep_context) -{ - struct timespec ts; - struct timeval tv; - struct aep_shared *aep_shared = aep_context->aep_shared; - - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec + 2; - ts.tv_nsec = 0; - - if (sem_timedwait(aep_context->semaphore, &ts) < 0) - return NULL; - - if (aep_shared->tail == aep_shared->head) - return NULL; - -// fprintf(stderr, "%d %d, ", aep_shared->tail, aep_shared->head); - - return &aep_shared->aep_result[aep_shared->tail]; -} - -/* - * helper for user code to deal with ringbuffer - */ - -void aep_free_result(struct aep_context *aep_context) -{ - struct aep_shared *aep_shared = aep_context->aep_shared; - - if (aep_shared->tail == sizeof(aep_shared->aep_result) / sizeof(aep_shared->aep_result[0]) - 1) - aep_shared->tail = 0; - else - aep_shared->tail++; -} -- cgit v1.2.3