Commit 9b3081f9 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Added locking to labcomm_internal_encoder_register and

labcomm_internal_encode, this triggered lots of changes to handling of 
stacked writer allocation. Twoway example is not finished yet.
parent 1112f3ba
......@@ -339,7 +339,7 @@ aspect C_Declarations {
}
public void SampleDecl.C_emitDecoderDeclaration(C_env env) {
env.println("void labcomm_decoder_register_" +
env.println("int labcomm_decoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_decoder *d,");
......@@ -366,7 +366,7 @@ aspect C_Declarations {
}
public void SampleDecl.C_emitEncoderDeclaration(C_env env) {
env.println("void labcomm_encoder_register_" +
env.println("int labcomm_encoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e);");
......@@ -617,7 +617,7 @@ aspect C_Decoder {
}
public void SampleDecl.C_emitDecoderRegisterHandler(C_env env) {
env.println("void labcomm_decoder_register_" +
env.println("int labcomm_decoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_decoder *d,");
......@@ -632,7 +632,7 @@ aspect C_Decoder {
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_decoder_register(");
env.println("return labcomm_internal_decoder_register(");
env.indent();
env.println("d,");
env.println("&labcomm_signature_" + env.prefix + getName() + ",");
......@@ -804,7 +804,7 @@ aspect C_Encoder {
}
public void SampleDecl.C_emitEncoderRegisterHandler(C_env env) {
env.println("void labcomm_encoder_register_" +
env.println("int labcomm_encoder_register_" +
env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e");
......@@ -812,7 +812,7 @@ aspect C_Encoder {
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_encoder_register(");
env.println("return labcomm_internal_encoder_register(");
env.indent();
env.println("e,");
env.println("&labcomm_signature_" + env.prefix + getName() + ",");
......
......@@ -28,7 +28,7 @@ gen/client: client.c
$(CC) -o $@ $(CFLAGS) $^ -lpthread \
-L../../lib/c -llabcomm -Tlabcomm.linkscript
gen/server: server.c gen/types.o gen/decimating.o
gen/server: server.c
$(CC) -o $@ $(CFLAGS) $^ -lpthread \
-L../../lib/c -llabcomm -Tlabcomm.linkscript
......@@ -38,9 +38,17 @@ clean:
gen/decimating.o: decimating.h
gen/decimating.o: gen/decimating_messages.h
gen/introspecting.o: introspecting.h
gen/introspecting.o: gen/introspecting_messages.h
gen/client.o: decimating.h
gen/client.o: gen/types.h
gen/client: gen/types.o
gen/client: gen/decimating.o
gen/client: gen/decimating_messages.o
gen/client: gen/types.o
gen/client: gen/introspecting.o
gen/client: gen/introspecting_messages.o
gen/server: gen/types.o
gen/server: gen/decimating.o
gen/server: gen/decimating_messages.o
gen/server: gen/introspecting.o
gen/server: gen/introspecting_messages.o
/*
client.c -- LabComm example of using stacked readers/writers.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm 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.
LabComm 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 <arpa/inet.h>
#include <linux/tcp.h>
#include <netdb.h>
......@@ -14,6 +35,7 @@
#include <labcomm_fd_writer.h>
#include <labcomm_pthread_mutex_lock.h>
#include "decimating.h"
#include "introspecting.h"
#include "gen/types.h"
static void handle_Sum(int32_t *value, void *context)
......@@ -47,6 +69,7 @@ int main(int argc, char *argv[])
struct sockaddr_in to;
int nodelay;
struct decimating *decimating;
struct introspecting *introspecting;
char *hostname;
int port;
struct labcomm_lock *lock;
......@@ -94,10 +117,18 @@ int main(int argc, char *argv[])
labcomm_fd_writer_new(fd, 0),
lock);
if (decimating == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
introspecting = introspecting_new(decimating->reader,
decimating->writer,
lock);
if (introspecting == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
decoder = labcomm_decoder_new(decimating->reader, lock);
encoder = labcomm_encoder_new(decimating->writer, lock);
decoder = labcomm_decoder_new(introspecting->reader, lock);
encoder = labcomm_encoder_new(introspecting->writer, lock);
pthread_t rdt;
labcomm_decoder_register_types_Sum(decoder, handle_Sum, NULL);
......
......@@ -29,10 +29,9 @@
struct decimating_private {
struct decimating decimating;
struct labcomm_lock *lock;
struct labcomm_encoder *encoder;
int encoder_initialized;
struct labcomm_decoder *decoder;
int decoder_initialized;
struct labcomm_reader_action_context reader_action_context;
struct labcomm_writer_action_context writer_action_context;
LABCOMM_SIGNATURE_ARRAY_DEF(decimation,
......@@ -62,26 +61,17 @@ static int wrap_reader_alloc(
struct labcomm_decoder *decoder,
char *labcomm_version)
{
struct decimating_private *decimating = action_context->context;
/* Stash away decoder for later use */
decimating->decoder = decoder;
return labcomm_reader_alloc(r, action_context->next,
decoder, labcomm_version);
}
int result;
static int wrap_reader_start(
struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context)
{
struct decimating_private *decimating = action_context->context;
if (! decimating->decoder_initialized) {
decimating->decoder_initialized = 1;
labcomm_decoder_register_decimating_messages_set_decimation(
decimating->decoder, set_decimation, decimating);
}
return labcomm_reader_start(r, action_context->next);
fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
/* Stash away decoder for later use */
result = labcomm_reader_alloc(r, action_context->next,
decoder, labcomm_version);
labcomm_decoder_register_decimating_messages_set_decimation(
decoder, set_decimation, decimating);
return result;
}
static int wrap_reader_ioctl(
......@@ -113,40 +103,47 @@ static int wrap_reader_ioctl(
struct labcomm_reader_action decimating_reader_action = {
.alloc = wrap_reader_alloc,
.free = NULL,
.start = wrap_reader_start,
.start = NULL,
.end = NULL,
.fill = NULL,
.ioctl = wrap_reader_ioctl
};
static void register_signatures(struct labcomm_encoder *encoder,
void *context)
{
labcomm_encoder_register_decimating_messages_set_decimation(
encoder);
}
static int wrap_writer_alloc(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder, char *labcomm_version)
struct labcomm_encoder *encoder, char *labcomm_version,
labcomm_encoder_enqueue enqueue)
{
int result;
struct decimating_private *decimating = action_context->context;
fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
/* Stash away encoder for later use */
decimating->encoder = encoder;
return labcomm_writer_alloc(w, action_context->next,
encoder, labcomm_version);
result = labcomm_writer_alloc(w, action_context->next,
encoder, labcomm_version, enqueue);
enqueue(encoder, register_signatures, NULL);
return result;
}
static int wrap_writer_start(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
int index, struct labcomm_signature *signature,
void *value)
{
struct decimating_private *decimating = action_context->context;
struct decimation *decimation;
if (! decimating->encoder_initialized) {
decimating->encoder_initialized = 1;
labcomm_encoder_register_decimating_messages_set_decimation(
decimating->encoder);
}
decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->decimation,
struct decimation, index);
decimation->current++;
......@@ -155,7 +152,7 @@ static int wrap_writer_start(
} else {
decimation->current = 0;
return labcomm_writer_start(w, action_context->next,
encoder, index, signature, value);
index, signature, value);
}
}
......@@ -196,10 +193,9 @@ extern struct decimating *decimating_new(
result->decimating.writer = writer;
/* Init other fields */
result->lock = lock;
result->encoder = NULL;
result->encoder_initialized = 0;
result->decoder = NULL;
result->decoder_initialized = 0;
LABCOMM_SIGNATURE_ARRAY_INIT(result->decimation, struct decimation);
goto out_ok;
......
typedef struct {
int index;
byte signature[_];
} has_signature_request;
typedef struct {
int index;
boolean result;
} has_signature_response;
sample has_signature_request encoder_has_signature_request;
sample has_signature_response encoder_has_signature_response;
sample has_signature_request decoder_has_signature_request;
sample has_signature_response decoder_has_signature_response;
\ No newline at end of file
/*
server.c -- LabComm example of using stacked readers/writers.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm 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.
LabComm 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 <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
......@@ -10,6 +31,7 @@
#include <labcomm_fd_reader.h>
#include <labcomm_fd_writer.h>
#include "decimating.h"
#include "introspecting.h"
#include "gen/types.h"
struct client {
......@@ -61,6 +83,7 @@ static void *run_client(void *arg)
{
struct client *client = arg;
struct decimating *decimating;
struct introspecting *introspecting;
struct labcomm_lock *lock;
printf("Client start\n");
......@@ -74,8 +97,15 @@ static void *run_client(void *arg)
/* Warning: might leak reader and writer at this point */
goto out;
}
client->decoder = labcomm_decoder_new(decimating->reader, lock);
client->encoder = labcomm_encoder_new(decimating->writer, lock);
introspecting = introspecting_new(decimating->reader,
decimating->writer,
lock);
if (introspecting == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
client->decoder = labcomm_decoder_new(introspecting->reader, lock);
client->encoder = labcomm_encoder_new(introspecting->writer, lock);
pthread_t rdt;
labcomm_decoder_register_types_A(client->decoder, handle_A, client);
......
......@@ -2,4 +2,5 @@ sample int A;
sample int B;
sample int Sum;
sample int Diff;
sample int Product;
sample void Terminate;
\ No newline at end of file
......@@ -45,7 +45,7 @@ liblabcomm.a: $(OBJS)
ar -r liblabcomm.a $^
liblabcomm.so.1: $(OBJS:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
labcomm.o : labcomm.c labcomm.h labcomm_private.h
......
This diff is collapsed.
......@@ -84,6 +84,12 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
*/
struct labcomm_lock;
int labcomm_lock_free(struct labcomm_lock *lock);
int labcomm_lock_lock(struct labcomm_lock *lock);
int labcomm_lock_unlock(struct labcomm_lock *lock);
int labcomm_lock_wait(struct labcomm_lock *lock, useconds_t usec);
int labcomm_lock_notify_all(struct labcomm_lock *lock);
/*
* Decoder
*/
......
......@@ -30,7 +30,8 @@
static int dyn_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
char *labcomm_version)
char *labcomm_version,
labcomm_encoder_enqueue enqueue)
{
w->data_size = 1000;
w->count = w->data_size;
......@@ -59,7 +60,6 @@ static int dyn_free(struct labcomm_writer *w,
static int dyn_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
int index,
struct labcomm_signature *signature,
void *value)
......
......@@ -112,15 +112,11 @@ static int fd_fill(struct labcomm_reader *r,
}
static int fd_start(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context)
struct labcomm_reader_action_context *action_context,
int index, struct labcomm_signature *signature,
void *value)
{
int available;
available = r->count - r->pos;
if (available == 0) {
available = fd_fill(r, action_context);
}
return available;
return 0;
}
static int fd_end(struct labcomm_reader *r,
......
......@@ -42,7 +42,8 @@ static int fd_flush(struct labcomm_writer *w,
static int fd_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
char *version)
char *version,
labcomm_encoder_enqueue enqueue)
{
w->data = malloc(BUFFER_SIZE);
if (! w->data) {
......@@ -82,7 +83,6 @@ static int fd_free(struct labcomm_writer *w,
static int fd_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
int index,
struct labcomm_signature *signature,
void *value)
......
......@@ -81,16 +81,9 @@
#define LABCOMM_IOSWN(type,nr,nargs) \
LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,nargs)
struct labcomm_ioctl_register_signature {
int index;
struct labcomm_signature *signature;
};
#define LABCOMM_IOCTL_REGISTER_SIGNATURE \
LABCOMM_IOW(0,1,struct labcomm_ioctl_register_signature)
#define LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN \
LABCOMM_IOR(0,2,int)
LABCOMM_IOR(0,1,int)
#define LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER \
LABCOMM_IOR(0,3,void*)
LABCOMM_IOR(0,2,void*)
#endif
......@@ -33,6 +33,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "labcomm.h"
/*
......@@ -69,17 +70,19 @@
/*
* Semi private lock declarations
*/
struct labcomm_lock;
struct labcomm_lock_action {
int (*alloc)(void *context);
int (*free)(void *context);
int (*read_lock)(void *context);
int (*read_unlock)(void *context);
int (*write_lock)(void *context);
int (*write_unlock)(void *context);
int (*free)(struct labcomm_lock *lock);
int (*acquire)(struct labcomm_lock *lock);
int (*release)(struct labcomm_lock *lock);
int (*wait)(struct labcomm_lock *lock, useconds_t usec);
int (*notify)(struct labcomm_lock *lock);
};
struct labcomm_lock {
const struct labcomm_lock_action action;
const struct labcomm_lock_action *action;
void *context;
};
/*
......@@ -95,20 +98,41 @@ typedef void (*labcomm_decoder_function)(
struct labcomm_reader_action_context;
struct labcomm_reader_action {
/* 'alloc' is called at the first invocation of 'labcomm_decoder_decode_one'
on the decoder containing the reader. If 'labcomm_version' != NULL
and non-empty the transport layer may use it to ensure that
compatible versions are used.
Returned value:
> 0 Number of bytes allocated for buffering
<= 0 Error
*/
int (*alloc)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
struct labcomm_decoder *decoder, char *labcomm_version);
/* 'free' returns the resources claimed by 'alloc' and might have other
reader specific side-effects as well.
Returned value:
== 0 Success
!= 0 Error
*/
int (*free)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
/* 'start' is called right after a sample has arrived. In the case of
a sample or typedef, 'value' == NULL.
*/
int (*start)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
struct labcomm_reader_action_context *action_context,
int index, struct labcomm_signature *signature,
void *value);
int (*end)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int (*fill)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int (*ioctl)(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int signature_index, struct labcomm_signature *signature,
int index, struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
};
......@@ -134,22 +158,23 @@ int labcomm_reader_alloc(struct labcomm_reader *r,
int labcomm_reader_free(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_start(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
struct labcomm_reader_action_context *action_context,
int index, struct labcomm_signature *signature,
void *value);
int labcomm_reader_end(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_fill(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context);
int labcomm_reader_ioctl(struct labcomm_reader *r,
struct labcomm_reader_action_context *action_context,
int signature_index,
struct labcomm_signature *signature,
int index, struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
/*
* Non typesafe registration function to be called from
* generated labcomm_decoder_register_* functions.
*/
void labcomm_internal_decoder_register(
int labcomm_internal_decoder_register(
struct labcomm_decoder *d,
struct labcomm_signature *s,
labcomm_decoder_function decoder,
......@@ -248,17 +273,31 @@ static inline char *labcomm_read_string(struct labcomm_reader *r)
typedef int (*labcomm_encoder_function)(
struct labcomm_writer *,
void *value);
typedef int (*labcomm_encoder_enqueue)(
struct labcomm_encoder *encoder,
void (*action)(struct labcomm_encoder *encoder,
void *context),
void *context);
struct labcomm_writer_action_context;
struct labcomm_writer_action {
int (*alloc)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder, char *labcomm_version);
struct labcomm_encoder *encoder, char *labcomm_version,
labcomm_encoder_enqueue enqueue);
int (*free)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
/* 'start' is called right before a sample is to be sent. In the
case of a sample or typedef, 'value' == NULL.
Returned value:
== 0 Success -> continue sending the sample
== -EALREADY Success -> silently skip sending the sample,
'end' will not be called
< 0 Error
*/
int (*start)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
int index, struct labcomm_signature *signature,
void *value);
int (*end)(struct labcomm_writer *w,
......@@ -267,7 +306,7 @@ struct labcomm_writer_action {
struct labcomm_writer_action_context *action_context);
int (*ioctl)(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int signature_index, struct labcomm_signature *signature,
int index, struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
};
......@@ -289,12 +328,12 @@ struct labcomm_writer {
int labcomm_writer_alloc(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
char *labcomm_version);
char *labcomm_version,
labcomm_encoder_enqueue enqueue);
int labcomm_writer_free(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int labcomm_writer_start(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm_encoder *encoder,
int index, struct labcomm_signature *signature,
void *value);
int labcomm_writer_end(struct labcomm_writer *w,
......@@ -303,11 +342,10 @@ int labcomm_writer_flush(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context);
int labcomm_writer_ioctl(struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int signature_index,
struct labcomm_signature *signature,
int index, struct labcomm_signature *signature,
uint32_t ioctl_action, va_list args);
void labcomm_internal_encoder_register(
int labcomm_internal_encoder_register(
struct labcomm_encoder *encoder,
struct labcomm_signature *signature,
labcomm_encoder_function encode);
......@@ -318,7 +356,6 @@ int labcomm_internal_encode(
labcomm_encoder_function encode,
void *value);
int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,