diff --git a/Pipe.sln b/Pipe.sln
new file mode 100644
index 0000000..c91d63d
--- /dev/null
+++ b/Pipe.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pipe", "Pipe\Pipe.vcxproj", "{FA5ADF78-687F-4538-B7DB-C62B46B697C7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x64.ActiveCfg = Debug|x64
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x64.Build.0 = Debug|x64
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x86.ActiveCfg = Debug|Win32
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x86.Build.0 = Debug|Win32
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x64.ActiveCfg = Release|x64
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x64.Build.0 = Release|x64
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x86.ActiveCfg = Release|Win32
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Pipe/Pipe.vcxproj b/Pipe/Pipe.vcxproj
new file mode 100644
index 0000000..7116a6a
--- /dev/null
+++ b/Pipe/Pipe.vcxproj
@@ -0,0 +1,122 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {FA5ADF78-687F-4538-B7DB-C62B46B697C7}
+ Pipe
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ true
+
+
+
+
+ Level3
+ Disabled
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+
+
+ true
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Pipe/Pipe.vcxproj.filters b/Pipe/Pipe.vcxproj.filters
new file mode 100644
index 0000000..763f921
--- /dev/null
+++ b/Pipe/Pipe.vcxproj.filters
@@ -0,0 +1,30 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/Pipe/main.c b/Pipe/main.c
new file mode 100644
index 0000000..9cdd3f5
--- /dev/null
+++ b/Pipe/main.c
@@ -0,0 +1,110 @@
+#include
+#include
+#include "ringbuffer.h"
+#include "pipe.h"
+
+void increment(pipe_t * const p)
+{
+ while (Pipe_isFilled(p))
+ {
+ uint32_t item = Pipe_Read(p);
+ item++;
+ Pipe_Write(p, item);
+ }
+}
+
+void square(pipe_t * const p)
+{
+ while (Pipe_isFilled(p))
+ {
+ uint32_t item = Pipe_Read(p);
+ item = item * item;
+ Pipe_Write(p, item);
+ }
+}
+
+void integrate(pipe_t * const p)
+{
+ static uint32_t state = 0;
+
+ while (Pipe_isFilled(p))
+ {
+ uint32_t item = Pipe_Read(p);
+ state = state + item;
+ Pipe_Write(p, state);
+ }
+}
+
+void sum(pipe_t * const p)
+{
+ uint32_t sum = 0;
+
+ while (Pipe_isFilled(p))
+ sum += Pipe_Read(p);
+ Pipe_Write(p, sum);
+}
+
+void average(pipe_t * const p)
+{
+ uint32_t sum = 0;
+ uint32_t element_counter = 0;
+ uint32_t average = 0;
+
+ while (Pipe_isFilled(p))
+ {
+ sum += Pipe_Read(p);
+ element_counter++;
+ }
+ average = sum / element_counter;
+ Pipe_Write(p, average);
+}
+
+int main(int argc, char * argv[])
+{
+ /* Create pipes and connect them */
+ Pipe_Create(increment_pipe, 4);
+ Pipe_Create(square_pipe, 4);
+ Pipe_Create(integrate_pipe, 8);
+ Pipe_Create(sum_pipe, 8);
+ Pipe_Create(average_pipe, 8);
+
+ Pipe_Connect(&increment_pipe, &integrate_pipe);
+ Pipe_Connect(&square_pipe, &integrate_pipe);
+ Pipe_CreateOutput(integrate_pipe, integrate_output_rb, 8);
+ Pipe_Connect(&integrate_pipe, &sum_pipe);
+ Pipe_CreateOutput(sum_pipe, sum_output_rb, 4);
+ Pipe_Connect(&integrate_pipe, &average_pipe);
+ Pipe_CreateOutput(average_pipe, average_output_rb, 4);
+
+ /* Generate input */
+ Pipe_Insert(&increment_pipe, 1);
+ Pipe_Insert(&increment_pipe, 3);
+ Pipe_Insert(&increment_pipe, 5);
+
+ Pipe_Insert(&square_pipe, 2);
+ Pipe_Insert(&square_pipe, 4);
+ Pipe_Insert(&square_pipe, 6);
+
+ /* run the functions */
+ increment(&increment_pipe);
+ square(&square_pipe);
+ integrate(&integrate_pipe);
+ sum(&sum_pipe);
+ average(&average_pipe);
+
+ /* print the output */
+ printf("Output:\n");
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("%d\n", RingBuffer_Read(&integrate_output_rb));
+ printf("\n");
+ printf("Summe: %d\n", RingBuffer_Read(&sum_output_rb));
+ printf("Average: %d\n", RingBuffer_Read(&average_output_rb));
+
+ getchar();
+
+ return 0;
+}
diff --git a/Pipe/pipe.h b/Pipe/pipe.h
new file mode 100644
index 0000000..74adbef
--- /dev/null
+++ b/Pipe/pipe.h
@@ -0,0 +1,89 @@
+#ifndef PIPE_H_
+#define PIPE_H_
+
+#include
+#include "ringbuffer.h"
+
+/* microsoft specific */
+#define inline __inline
+
+/* number of counts */
+#define PIPE_OUTPUT_COUNT 4
+
+typedef struct
+{
+ ringbuffer_t * input;
+ ringbuffer_t *output[PIPE_OUTPUT_COUNT];
+ uint8_t output_count;
+} pipe_t;
+
+/***********************************/
+/* Functions to contruct pipe mesh */
+/***********************************/
+
+static inline void Pipe_Init(pipe_t * const p, ringbuffer_t * const arg_input)
+{
+ p->input = arg_input;
+
+ for (uint8_t i = 0; i < PIPE_OUTPUT_COUNT; i++)
+ p->output[i] = NULL;
+
+ p->output_count = 0;
+}
+
+static inline void Pipe_Connect(pipe_t * const a, pipe_t * const b)
+{
+ a->output[a->output_count] = b->input;
+ a->output_count++;
+}
+
+static inline void Pipe_AddOutput(pipe_t * const p, ringbuffer_t * const rb)
+{
+ p->output[p->output_count] = rb;
+ p->output_count++;
+}
+
+#define Concat2(a, b) a ## b
+#define Concat(a, b) Concat2(a, b)
+#define SizeOfArray(arg) ( sizeof(arg) / sizeof(arg[0]) )
+
+#define Pipe_Create(arg_name, arg_size) \
+ static uint32_t Concat(buffer, __LINE__)[arg_size]; \
+ ringbuffer_t arg_name ## _rb; \
+ RingBuffer_InitFromArray(&arg_name ## _rb, Concat(buffer, __LINE__), SizeOfArray(Concat(buffer, __LINE__))); \
+ pipe_t arg_name; \
+ Pipe_Init(&arg_name, &arg_name ## _rb)
+
+#define Pipe_CreateOutput(arg_pipe, arg_name, arg_size) \
+ static uint32_t Concat(buffer, __LINE__)[arg_size]; \
+ ringbuffer_t arg_name; \
+ RingBuffer_InitFromArray(&arg_name, Concat(buffer, __LINE__), SizeOfArray(Concat(buffer, __LINE__))); \
+ Pipe_AddOutput(&arg_pipe, &arg_name);
+
+
+/************************************/
+/* Functions to work with pipe mesh */
+/************************************/
+
+static inline void Pipe_Insert(pipe_t * const p, uint32_t elem)
+{
+ RingBuffer_Write(p->input, elem);
+}
+
+static inline uint32_t Pipe_Read(pipe_t * p)
+{
+ return RingBuffer_Read(p->input);
+}
+
+static inline void Pipe_Write(pipe_t * p, uint32_t elem)
+{
+ for (uint8_t i = 0; i < p->output_count; i++)
+ RingBuffer_Write(p->output[i], elem);
+}
+
+static inline uint8_t Pipe_isFilled(pipe_t * p)
+{
+ return RingBuffer_IsFilled(p->input);
+}
+
+#endif
diff --git a/Pipe/ringbuffer.h b/Pipe/ringbuffer.h
new file mode 100644
index 0000000..f7e7799
--- /dev/null
+++ b/Pipe/ringbuffer.h
@@ -0,0 +1,96 @@
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#include
+
+#define inline __inline
+
+typedef struct {
+ uint32_t * reader;
+ uint32_t * writer;
+ uint32_t * start;
+ uint32_t * end;
+ uint8_t write_failed;
+ uint8_t read_failed;
+} ringbuffer_t;
+
+/* Use Array as RingBuffer */
+static inline void RingBuffer_InitFromArray(ringbuffer_t * const rb, uint32_t * const array, const uint32_t size)
+{
+ rb->start = rb->reader = rb->writer = array;
+ rb->end = array + size - 1;
+ rb->write_failed = rb->read_failed = 0;
+}
+
+static inline uint32_t * RingBuffer_GetNextWriterAddress(const ringbuffer_t * const rb)
+{
+ uint32_t * next_address = rb->writer;
+
+ if (next_address == rb->end)
+ next_address = rb->start;
+ else
+ next_address++;
+
+ return next_address;
+}
+
+static inline uint8_t RingBuffer_IsFull(const ringbuffer_t * const rb)
+{
+ if (RingBuffer_GetNextWriterAddress(rb) == rb->reader)
+ return 1;
+ return 0;
+}
+
+static inline uint8_t RingBuffer_IsEmpty(const ringbuffer_t * const rb)
+{
+ if (rb->writer == rb->reader)
+ return 1;
+ return 0;
+}
+
+static inline uint8_t RingBuffer_IsFilled(const ringbuffer_t * const rb)
+{
+ return !RingBuffer_IsEmpty(rb);
+}
+
+/* Write elem into RingBuffer. */
+static inline void RingBuffer_Write(ringbuffer_t * const rb, const uint32_t elem)
+{
+ if (!RingBuffer_IsFull(rb))
+ {
+ *(rb->writer) = elem;
+
+ if (rb->writer == rb->end)
+ rb->writer = rb->start;
+ else
+ rb->writer++;
+ }
+ else
+ {
+ rb->write_failed = 1;
+ }
+}
+
+/* Read value from RingBuffer and returns it. */
+static inline uint32_t RingBuffer_Read(ringbuffer_t * const rb)
+{
+ uint32_t ret = 0;
+
+ if (!RingBuffer_IsEmpty(rb))
+ {
+ ret = *(rb->reader);
+
+ if (rb->reader == rb->end)
+ rb->reader = rb->start;
+ else
+ rb->reader++;
+ }
+ else
+ {
+ rb->read_failed = 1;
+ }
+
+ return ret;
+}
+
+#endif