Thread test works!
This commit is contained in:
44
.cproject
Normal file
44
.cproject
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||||
|
<cconfiguration id="0.598556019">
|
||||||
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.598556019" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||||
|
<externalSettings/>
|
||||||
|
<extensions>
|
||||||
|
<extension id="org.eclipse.cdt.ui.Regex Error Parser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
</extensions>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<configuration buildProperties="" description="" errorParsers="org.eclipse.cdt.ui.Regex Error Parser" id="0.598556019" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||||
|
<folderInfo id="0.598556019." name="/" resourcePath="">
|
||||||
|
<toolChain errorParsers="" id="org.eclipse.cdt.build.core.prefbase.toolchain.1235403699" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||||
|
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1235403699.413443094" name=""/>
|
||||||
|
<builder arguments="-f "../Tool/toolchain/opt/compiler.opt" --core=tc1.3.1 --cpu=tc1782 --source -f "${selected_resource_loc}/../../tmp/Includes.opt" -f "${selected_resource_loc}/../../opt/compiler.opt" -o "${selected_resource_loc}/../../tmp/trash" "${selected_resource_loc}"" command=""d:/tools/Tasking/TriCore/3.2r3/ctc/bin/ctc.exe"" enableCleanBuild="false" errorParsers="" id="org.eclipse.cdt.build.core.settings.default.builder.1123914364" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||||
|
<tool errorParsers="" id="org.eclipse.cdt.build.core.settings.holder.libs.1396912558" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||||
|
<tool errorParsers="" id="org.eclipse.cdt.build.core.settings.holder.1043027053" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1089353706" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
<tool errorParsers="" id="org.eclipse.cdt.build.core.settings.holder.2057322761" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1478445541" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
<tool errorParsers="" id="org.eclipse.cdt.build.core.settings.holder.816818701" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1814575165" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
</toolChain>
|
||||||
|
</folderInfo>
|
||||||
|
</configuration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
|
</cconfiguration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<project id="Pipe.null.2005735511" name="Pipe"/>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="scannerConfiguration">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
<scannerConfigBuildInfo instanceId="0.598556019">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||||
|
</cproject>
|
||||||
26
.project
Normal file
26
.project
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Pipe</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||||
|
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||||
|
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@ -114,6 +114,7 @@
|
|||||||
<ClCompile Include="threads.c" />
|
<ClCompile Include="threads.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="connector.h" />
|
||||||
<ClInclude Include="pipe.h" />
|
<ClInclude Include="pipe.h" />
|
||||||
<ClInclude Include="ringbuffer.h" />
|
<ClInclude Include="ringbuffer.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -29,5 +29,8 @@
|
|||||||
<ClInclude Include="ringbuffer.h">
|
<ClInclude Include="ringbuffer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="connector.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
0
Pipe/buffer.txt
Normal file
0
Pipe/buffer.txt
Normal file
100
Pipe/buffer1.txt
Normal file
100
Pipe/buffer1.txt
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
11
|
||||||
|
12
|
||||||
|
13
|
||||||
|
14
|
||||||
|
15
|
||||||
|
16
|
||||||
|
17
|
||||||
|
18
|
||||||
|
19
|
||||||
|
20
|
||||||
|
21
|
||||||
|
22
|
||||||
|
23
|
||||||
|
24
|
||||||
|
25
|
||||||
|
26
|
||||||
|
27
|
||||||
|
28
|
||||||
|
29
|
||||||
|
30
|
||||||
|
31
|
||||||
|
32
|
||||||
|
33
|
||||||
|
34
|
||||||
|
35
|
||||||
|
36
|
||||||
|
37
|
||||||
|
38
|
||||||
|
39
|
||||||
|
40
|
||||||
|
41
|
||||||
|
42
|
||||||
|
43
|
||||||
|
44
|
||||||
|
45
|
||||||
|
46
|
||||||
|
47
|
||||||
|
48
|
||||||
|
49
|
||||||
|
50
|
||||||
|
51
|
||||||
|
52
|
||||||
|
53
|
||||||
|
54
|
||||||
|
55
|
||||||
|
56
|
||||||
|
57
|
||||||
|
58
|
||||||
|
59
|
||||||
|
60
|
||||||
|
61
|
||||||
|
62
|
||||||
|
63
|
||||||
|
64
|
||||||
|
65
|
||||||
|
66
|
||||||
|
67
|
||||||
|
68
|
||||||
|
69
|
||||||
|
70
|
||||||
|
71
|
||||||
|
72
|
||||||
|
73
|
||||||
|
74
|
||||||
|
75
|
||||||
|
76
|
||||||
|
77
|
||||||
|
78
|
||||||
|
79
|
||||||
|
80
|
||||||
|
81
|
||||||
|
82
|
||||||
|
83
|
||||||
|
84
|
||||||
|
85
|
||||||
|
86
|
||||||
|
87
|
||||||
|
88
|
||||||
|
89
|
||||||
|
90
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
100
Pipe/buffer2.txt
Normal file
100
Pipe/buffer2.txt
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
11
|
||||||
|
12
|
||||||
|
13
|
||||||
|
14
|
||||||
|
15
|
||||||
|
16
|
||||||
|
17
|
||||||
|
18
|
||||||
|
19
|
||||||
|
20
|
||||||
|
21
|
||||||
|
22
|
||||||
|
23
|
||||||
|
24
|
||||||
|
25
|
||||||
|
26
|
||||||
|
27
|
||||||
|
28
|
||||||
|
29
|
||||||
|
30
|
||||||
|
31
|
||||||
|
32
|
||||||
|
33
|
||||||
|
34
|
||||||
|
35
|
||||||
|
36
|
||||||
|
37
|
||||||
|
38
|
||||||
|
39
|
||||||
|
40
|
||||||
|
41
|
||||||
|
42
|
||||||
|
43
|
||||||
|
44
|
||||||
|
45
|
||||||
|
46
|
||||||
|
47
|
||||||
|
48
|
||||||
|
49
|
||||||
|
50
|
||||||
|
51
|
||||||
|
52
|
||||||
|
53
|
||||||
|
54
|
||||||
|
55
|
||||||
|
56
|
||||||
|
57
|
||||||
|
58
|
||||||
|
59
|
||||||
|
60
|
||||||
|
61
|
||||||
|
62
|
||||||
|
63
|
||||||
|
64
|
||||||
|
65
|
||||||
|
66
|
||||||
|
67
|
||||||
|
68
|
||||||
|
69
|
||||||
|
70
|
||||||
|
71
|
||||||
|
72
|
||||||
|
73
|
||||||
|
74
|
||||||
|
75
|
||||||
|
76
|
||||||
|
77
|
||||||
|
78
|
||||||
|
79
|
||||||
|
80
|
||||||
|
81
|
||||||
|
82
|
||||||
|
83
|
||||||
|
84
|
||||||
|
85
|
||||||
|
86
|
||||||
|
87
|
||||||
|
88
|
||||||
|
89
|
||||||
|
90
|
||||||
|
91
|
||||||
|
92
|
||||||
|
93
|
||||||
|
94
|
||||||
|
95
|
||||||
|
96
|
||||||
|
97
|
||||||
|
98
|
||||||
|
99
|
||||||
|
100
|
||||||
|
101
|
||||||
|
102
|
||||||
|
0
|
||||||
95
Pipe/connector.h
Normal file
95
Pipe/connector.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#ifndef CONNECTION_H_
|
||||||
|
#define CONNECTION_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
|
/* microsoft specific */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A connection is an array of pointers, pointing to ringbuffers. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ringbuffer_t ** connection;
|
||||||
|
uint32_t connection_count;
|
||||||
|
uint32_t connection_max;
|
||||||
|
} connector_t;
|
||||||
|
|
||||||
|
static inline uint8_t Connector_IsFull(connector_t * const connector)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < connector->connection_count; i++)
|
||||||
|
{
|
||||||
|
if (RingBuffer_IsFull(connector->connection[i]))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t Connector_IsEmpty(connector_t * const connector)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < connector->connection_count; i++)
|
||||||
|
{
|
||||||
|
if (!RingBuffer_IsEmpty(connector->connection[i]))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t Connector_IsFilled(connector_t * const connector)
|
||||||
|
{
|
||||||
|
return !Connector_IsEmpty(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t Connector_Read(connector_t * const connector)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
while ( RingBuffer_IsEmpty(connector->connection[i]) && (i < connector->connection_count) )
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i == connector->connection_count)
|
||||||
|
return 0;
|
||||||
|
return RingBuffer_Read(connector->connection[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Connector_Write(connector_t * const connector, uint32_t element)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < connector->connection_count; i++)
|
||||||
|
RingBuffer_Write(connector->connection[i], element);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Connector_Insert(connector_t * const connector, uint32_t ring_buffer_index, uint32_t element)
|
||||||
|
{
|
||||||
|
RingBuffer_Write(connector->connection[ring_buffer_index], element);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Connector_Add(connector_t * const connector, ringbuffer_t * ring_buffer)
|
||||||
|
{
|
||||||
|
if (connector->connection_count < connector->connection_max)
|
||||||
|
{
|
||||||
|
connector->connection[connector->connection_count] = ring_buffer;
|
||||||
|
connector->connection_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Connector_Init(connector_t * const connector, ringbuffer_t *buffer[], uint32_t buffer_size)
|
||||||
|
{
|
||||||
|
connector->connection = &buffer[0];
|
||||||
|
connector->connection_count = 0;
|
||||||
|
connector->connection_max = buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Concat2(a, b) a ## b
|
||||||
|
#define Concat(a, b) Concat2(a, b)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Macro for the creation of a connector.
|
||||||
|
*/
|
||||||
|
#define Connector_Create(name, size) \
|
||||||
|
ringbuffer_t *Concat(name, Concat(_buffer, __LINE__))[size]; \
|
||||||
|
connector_t name; \
|
||||||
|
Connector_Init(&name, Concat(name, Concat(_buffer, __LINE__)), size); \
|
||||||
|
|
||||||
|
#endif
|
||||||
67
Pipe/main.c
67
Pipe/main.c
@ -4,6 +4,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "connector.h"
|
||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -13,7 +14,7 @@
|
|||||||
/* Integrate every element of the signal. */
|
/* Integrate every element of the signal. */
|
||||||
void increment(pipe_t * const p)
|
void increment(pipe_t * const p)
|
||||||
{
|
{
|
||||||
while (Pipe_isFilled(p))
|
while (Pipe_IsFilled(p))
|
||||||
{
|
{
|
||||||
uint32_t item = Pipe_Read(p);
|
uint32_t item = Pipe_Read(p);
|
||||||
item++;
|
item++;
|
||||||
@ -24,7 +25,7 @@ void increment(pipe_t * const p)
|
|||||||
/* Square every element of the signal. */
|
/* Square every element of the signal. */
|
||||||
void square(pipe_t * const p)
|
void square(pipe_t * const p)
|
||||||
{
|
{
|
||||||
while (Pipe_isFilled(p))
|
while (Pipe_IsFilled(p))
|
||||||
{
|
{
|
||||||
uint32_t item = Pipe_Read(p);
|
uint32_t item = Pipe_Read(p);
|
||||||
item = item * item;
|
item = item * item;
|
||||||
@ -37,7 +38,7 @@ void integrate(pipe_t * const pipe)
|
|||||||
{
|
{
|
||||||
uint32_t state = *((uint32_t*)pipe->state);
|
uint32_t state = *((uint32_t*)pipe->state);
|
||||||
|
|
||||||
while (Pipe_isFilled(pipe))
|
while (Pipe_IsFilled(pipe))
|
||||||
{
|
{
|
||||||
uint32_t item = Pipe_Read(pipe);
|
uint32_t item = Pipe_Read(pipe);
|
||||||
state = state + item;
|
state = state + item;
|
||||||
@ -52,7 +53,7 @@ void sum(pipe_t * const pipe)
|
|||||||
{
|
{
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
|
|
||||||
while (Pipe_isFilled(pipe))
|
while (Pipe_IsFilled(pipe))
|
||||||
sum += Pipe_Read(pipe);
|
sum += Pipe_Read(pipe);
|
||||||
Pipe_Write(pipe, sum);
|
Pipe_Write(pipe, sum);
|
||||||
}
|
}
|
||||||
@ -64,7 +65,7 @@ void average(pipe_t * const pipe)
|
|||||||
uint32_t element_counter = 0;
|
uint32_t element_counter = 0;
|
||||||
uint32_t average = 0;
|
uint32_t average = 0;
|
||||||
|
|
||||||
while (Pipe_isFilled(pipe))
|
while (Pipe_IsFilled(pipe))
|
||||||
{
|
{
|
||||||
sum += Pipe_Read(pipe);
|
sum += Pipe_Read(pipe);
|
||||||
element_counter++;
|
element_counter++;
|
||||||
@ -77,27 +78,30 @@ void average(pipe_t * const pipe)
|
|||||||
void print(pipe_t * const pipe)
|
void print(pipe_t * const pipe)
|
||||||
{
|
{
|
||||||
printf("\nOutput:\n");
|
printf("\nOutput:\n");
|
||||||
while (Pipe_isFilled(pipe))
|
while (Pipe_IsFilled(pipe))
|
||||||
printf("%d\n", Pipe_Read(pipe));
|
printf("%d\n", Pipe_Read(pipe));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logging function. Set by user. */
|
/* Logging function. Set by user. */
|
||||||
void log(pipe_t * const source, pipe_t * const target, uint32_t element)
|
void log(pipe_t * const source, pipe_t * const target, uint32_t element)
|
||||||
{
|
{
|
||||||
if (Pipe_isFull(target))
|
//if (Pipe_IsFull(target))
|
||||||
printf("Error: Pipe %s is full!\n", target->name);
|
// printf("Error: Pipe %s is full!\n", target->name);
|
||||||
|
|
||||||
if (source->state == NULL && target->state == NULL)
|
//if (source->state == NULL && target->state == NULL)
|
||||||
printf("%s -> %d -> %s\n", source->name, element, target->name);
|
// printf("%s -> %d -> %s\n", source->name, element, target->name);
|
||||||
else if (source->state != NULL && target->state != NULL)
|
//else if (source->state != NULL && target->state != NULL)
|
||||||
printf("%s(%d) -> %d -> %s(%d)\n", source->name, *((uint32_t*)source->state), element, target->name, *((uint32_t*)target->state));
|
// printf("%s(%d) -> %d -> %s(%d)\n", source->name, *((uint32_t*)source->state), element, target->name, *((uint32_t*)target->state));
|
||||||
else if (source->state != NULL)
|
//else if (source->state != NULL)
|
||||||
printf("%s(%d) -> %d -> %s\n", source->name, *((uint32_t*)source->state), element, target->name);
|
// printf("%s(%d) -> %d -> %s\n", source->name, *((uint32_t*)source->state), element, target->name);
|
||||||
else
|
//else
|
||||||
printf("%s -> %d -> %s(%d)\n", source->name, element, target->name, *((uint32_t*)target->state));
|
// printf("%s -> %d -> %s(%d)\n", source->name, element, target->name, *((uint32_t*)target->state));
|
||||||
|
|
||||||
|
printf("%s: %d\n", source->name, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void threads(void);
|
extern void threads(uint32_t loops);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
@ -105,19 +109,22 @@ int main(int argc, char *argv[])
|
|||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
/* Create pipes and connect them */
|
/* Create pipes and connect them */
|
||||||
Pipe_Create(increment_pipe, 4, 1, NULL, log);
|
Pipe_Create(increment_pipe, 1, 1, NULL, log);
|
||||||
Pipe_Create(square_pipe, 4, 1, NULL, log);
|
Pipe_Create(square_pipe, 1, 1, NULL, log);
|
||||||
Pipe_Create(integrate_pipe, 8, 2, &counter, log);
|
Pipe_Create(integrate_pipe, 2, 2, &counter, log);
|
||||||
Pipe_Create(sum_pipe, 8, 2, NULL, log);
|
Pipe_Create(sum_pipe, 1, 1, NULL, log);
|
||||||
Pipe_Create(average_pipe, 8, 2, NULL, log);
|
Pipe_Create(average_pipe, 1, 1, NULL, log);
|
||||||
Pipe_Create(print_pipe, 4, 2, NULL, log);
|
Pipe_Create(print_pipe, 2, 1, NULL, log);
|
||||||
|
|
||||||
Pipe_Connect(&increment_pipe, &integrate_pipe);
|
Pipe_CreateInputBuffer(increment_pipe, 4);
|
||||||
Pipe_Connect(&square_pipe, &integrate_pipe);
|
Pipe_CreateInputBuffer(square_pipe, 4);
|
||||||
Pipe_Connect(&integrate_pipe, &sum_pipe);
|
|
||||||
Pipe_Connect(&integrate_pipe, &average_pipe);
|
Pipe_CreateConnection(increment_pipe, integrate_pipe, 4);
|
||||||
Pipe_Connect(&sum_pipe, &print_pipe);
|
Pipe_CreateConnection(square_pipe, integrate_pipe, 4);
|
||||||
Pipe_Connect(&average_pipe, &print_pipe);
|
Pipe_CreateConnection(integrate_pipe, sum_pipe, 8);
|
||||||
|
Pipe_CreateConnection(integrate_pipe, average_pipe, 8);
|
||||||
|
Pipe_CreateConnection(sum_pipe, print_pipe, 4);
|
||||||
|
Pipe_CreateConnection(average_pipe, print_pipe, 4);
|
||||||
|
|
||||||
/* Create Input */
|
/* Create Input */
|
||||||
Pipe_Insert(&increment_pipe, 1);
|
Pipe_Insert(&increment_pipe, 1);
|
||||||
@ -140,7 +147,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
threads();
|
threads(atoi(argv[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
78
Pipe/pipe.h
78
Pipe/pipe.h
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "connector.h"
|
||||||
|
|
||||||
/* microsoft specific */
|
/* microsoft specific */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -11,11 +12,9 @@
|
|||||||
|
|
||||||
typedef struct pipe_tt
|
typedef struct pipe_tt
|
||||||
{
|
{
|
||||||
ringbuffer_t * input;
|
connector_t * input_connector;
|
||||||
|
connector_t * output_connector;
|
||||||
void * state;
|
void * state;
|
||||||
struct pipe_tt ** connection;
|
|
||||||
uint32_t connection_count;
|
|
||||||
uint32_t connection_max;
|
|
||||||
char * name;
|
char * name;
|
||||||
void(*log_function)(struct pipe_tt * from, struct pipe_tt * to, uint32_t elem);
|
void(*log_function)(struct pipe_tt * from, struct pipe_tt * to, uint32_t elem);
|
||||||
} pipe_t;
|
} pipe_t;
|
||||||
@ -31,7 +30,7 @@ So the signal can inserted to the pipe system.
|
|||||||
*/
|
*/
|
||||||
static inline void Pipe_Insert(pipe_t * const pipe, uint32_t element)
|
static inline void Pipe_Insert(pipe_t * const pipe, uint32_t element)
|
||||||
{
|
{
|
||||||
RingBuffer_Write(pipe->input, element);
|
Connector_Insert(pipe->input_connector, 0, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -40,7 +39,7 @@ Used inside functions of the pipe system.
|
|||||||
*/
|
*/
|
||||||
static inline uint32_t Pipe_Read(pipe_t * pipe)
|
static inline uint32_t Pipe_Read(pipe_t * pipe)
|
||||||
{
|
{
|
||||||
return RingBuffer_Read(pipe->input);
|
return Connector_Read(pipe->input_connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -49,29 +48,26 @@ Used inside functions of the pipe system.
|
|||||||
*/
|
*/
|
||||||
static inline void Pipe_Write(pipe_t * pipe, uint32_t element)
|
static inline void Pipe_Write(pipe_t * pipe, uint32_t element)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < pipe->connection_count; i++)
|
pipe->log_function(pipe, NULL, element);
|
||||||
{
|
Connector_Write(pipe->output_connector, element);
|
||||||
pipe->log_function(pipe, pipe->connection[i], element);
|
|
||||||
RingBuffer_Write(pipe->connection[i]->input, element);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if the pipe contents elements.
|
Check if the pipe contents elements.
|
||||||
Used inside functions of the pipe system.
|
Used inside functions of the pipe system.
|
||||||
*/
|
*/
|
||||||
static inline uint8_t Pipe_isFilled(pipe_t * pipe)
|
static inline uint8_t Pipe_IsFilled(pipe_t * pipe)
|
||||||
{
|
{
|
||||||
return RingBuffer_IsFilled(pipe->input);
|
return Connector_IsFilled(pipe->input_connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if the pipe has no place left for new elements.
|
Check if the pipe has no place left for new elements.
|
||||||
Usefull for the logging.
|
Usefull for the logging.
|
||||||
*/
|
*/
|
||||||
static inline uint8_t Pipe_isFull(const pipe_t * pipe)
|
static inline uint8_t Pipe_IsFull(const pipe_t * pipe)
|
||||||
{
|
{
|
||||||
return RingBuffer_IsFull(pipe->input);
|
return Connector_IsFull(pipe->input_connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -80,7 +76,7 @@ Shall be set by user.
|
|||||||
*/
|
*/
|
||||||
static inline void Pipe_Log(pipe_t * const source, pipe_t * const target, uint32_t element)
|
static inline void Pipe_Log(pipe_t * const source, pipe_t * const target, uint32_t element)
|
||||||
{
|
{
|
||||||
if (Pipe_isFull(target))
|
if (Pipe_IsFull(target))
|
||||||
printf("Error: Pipe %s is full!\n", target->name);
|
printf("Error: Pipe %s is full!\n", target->name);
|
||||||
|
|
||||||
if (source->state == NULL && target->state == NULL)
|
if (source->state == NULL && target->state == NULL)
|
||||||
@ -100,7 +96,6 @@ static inline void Pipe_Log(pipe_t * const source, pipe_t * const target, uint32
|
|||||||
|
|
||||||
#define Concat2(a, b) a ## b
|
#define Concat2(a, b) a ## b
|
||||||
#define Concat(a, b) Concat2(a, b)
|
#define Concat(a, b) Concat2(a, b)
|
||||||
#define SizeOfArray(arg) ( sizeof(arg) / sizeof(arg[0]) )
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Macro for the creation of a pipe.
|
Macro for the creation of a pipe.
|
||||||
@ -111,13 +106,11 @@ arg_conn_count is the number of outgoing connections.
|
|||||||
arg_state is the given state, which can be used in the function.
|
arg_state is the given state, which can be used in the function.
|
||||||
arg_log is the log function, called when an element is sent.
|
arg_log is the log function, called when an element is sent.
|
||||||
*/
|
*/
|
||||||
#define Pipe_Create(arg_name, arg_size, arg_conn_count, arg_state, arg_log) \
|
#define Pipe_Create(name, input_connection_count, output_connection_count, state, log) \
|
||||||
static uint32_t Concat(arg_name, Concat(_buffer, __LINE__))[arg_size]; \
|
static Connector_Create(Concat(name, Concat(_input_connector, __LINE__)), input_connection_count); \
|
||||||
ringbuffer_t arg_name ## _rb; \
|
static Connector_Create(Concat(name, Concat(_output_connector, __LINE__)), output_connection_count); \
|
||||||
RingBuffer_InitFromArray(&arg_name ## _rb, Concat(arg_name, Concat(_buffer, __LINE__)), arg_size); \
|
pipe_t name; \
|
||||||
pipe_t arg_name; \
|
Pipe_Init(&name, &Concat(name, Concat(_input_connector, __LINE__)), &Concat(name, Concat(_output_connector, __LINE__)), state, #name, log)
|
||||||
static pipe_t *Concat(arg_name, Concat(_connection_buffer, __LINE__))[arg_conn_count]; \
|
|
||||||
Pipe_Init(&arg_name, &arg_name ## _rb, Concat(arg_name, Concat(_connection_buffer, __LINE__)), arg_conn_count, arg_state, #arg_name, arg_log)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initializes a pipe.
|
Initializes a pipe.
|
||||||
@ -127,23 +120,16 @@ A Name and a logging function are usefull to track the dataflow.
|
|||||||
*/
|
*/
|
||||||
static inline void Pipe_Init(
|
static inline void Pipe_Init(
|
||||||
pipe_t * const pipe,
|
pipe_t * const pipe,
|
||||||
ringbuffer_t * const input,
|
connector_t * input_connector,
|
||||||
pipe_t ** pipe_connections,
|
connector_t * output_connector,
|
||||||
uint32_t connection_max,
|
|
||||||
void * state,
|
void * state,
|
||||||
char * const name,
|
char * const name,
|
||||||
void(*log_function)(struct pipe_tt * source, struct pipe_tt * target, uint32_t element)
|
void(*log_function)(struct pipe_tt * source, struct pipe_tt * target, uint32_t element)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
pipe->input = input;
|
pipe->input_connector = input_connector;
|
||||||
|
pipe->output_connector = output_connector;
|
||||||
pipe->state = state;
|
pipe->state = state;
|
||||||
pipe->connection = pipe_connections;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < connection_max; i++)
|
|
||||||
pipe->connection[i] = NULL;
|
|
||||||
|
|
||||||
pipe->connection_count = 0;
|
|
||||||
pipe->connection_max = connection_max;
|
|
||||||
pipe->name = name;
|
pipe->name = name;
|
||||||
|
|
||||||
if (log_function == NULL)
|
if (log_function == NULL)
|
||||||
@ -153,13 +139,23 @@ static inline void Pipe_Init(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Connect two pipes. Pipe a sends elements to pipe b. */
|
/* Connect two pipes. Pipe a sends elements to pipe b. */
|
||||||
static inline void Pipe_Connect(pipe_t * const source, pipe_t * const target)
|
static inline void Pipe_Connect(pipe_t * const source, pipe_t * const target, ringbuffer_t * ring_buffer)
|
||||||
{
|
{
|
||||||
if (source->connection_count < source->connection_max)
|
Connector_Add(source->output_connector, ring_buffer);
|
||||||
{
|
Connector_Add(target->input_connector, ring_buffer);
|
||||||
source->connection[source->connection_count] = target;
|
|
||||||
source->connection_count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define Pipe_CreateConnection(source, target, size) \
|
||||||
|
RingBuffer_Create(Concat(connector_ring_buffer, __LINE__), size); \
|
||||||
|
Pipe_Connect(&source, &target, &Concat(connector_ring_buffer, __LINE__))
|
||||||
|
|
||||||
|
static inline void Pipe_AddInputBuffer(pipe_t * const pipe, ringbuffer_t * input_buffer)
|
||||||
|
{
|
||||||
|
Connector_Add(pipe->input_connector, input_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Pipe_CreateInputBuffer(pipe_name, size) \
|
||||||
|
RingBuffer_Create(Concat(connector_ring_buffer, __LINE__), size); \
|
||||||
|
Pipe_AddInputBuffer(&pipe_name, &Concat(connector_ring_buffer, __LINE__))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -15,10 +15,13 @@ typedef struct {
|
|||||||
} ringbuffer_t;
|
} ringbuffer_t;
|
||||||
|
|
||||||
/* Use Array as RingBuffer */
|
/* Use Array as RingBuffer */
|
||||||
static inline void RingBuffer_InitFromArray(ringbuffer_t * const ring_buffer, uint32_t * const array, uint32_t size)
|
static inline void RingBuffer_Init(ringbuffer_t * const ring_buffer, uint32_t * const array, uint32_t size)
|
||||||
{
|
{
|
||||||
ring_buffer->start = ring_buffer->reader = ring_buffer->writer = &array[0];
|
ring_buffer->start = ring_buffer->reader = ring_buffer->writer = &array[0];
|
||||||
ring_buffer->end = &array[0] + size - 1;
|
ring_buffer->end = &array[0] + size - 1;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; i++)
|
||||||
|
array[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t * RingBuffer_NextAddress(ringbuffer_t * const ring_buffer, uint32_t * const pointer)
|
static inline uint32_t * RingBuffer_NextAddress(ringbuffer_t * const ring_buffer, uint32_t * const pointer)
|
||||||
@ -66,11 +69,19 @@ static inline uint32_t RingBuffer_Read(ringbuffer_t * const ring_buffer)
|
|||||||
if (!RingBuffer_IsEmpty(ring_buffer))
|
if (!RingBuffer_IsEmpty(ring_buffer))
|
||||||
{
|
{
|
||||||
element = *(ring_buffer->reader);
|
element = *(ring_buffer->reader);
|
||||||
*(ring_buffer->reader) = 5;
|
*(ring_buffer->reader) = 30;
|
||||||
ring_buffer->reader = RingBuffer_NextAddress(ring_buffer, ring_buffer->reader);
|
ring_buffer->reader = RingBuffer_NextAddress(ring_buffer, ring_buffer->reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Macro for the creation of a ring buffer.
|
||||||
|
*/
|
||||||
|
#define RingBuffer_Create(name, size) \
|
||||||
|
uint32_t Concat(name, Concat(_buffer, __LINE__))[size]; \
|
||||||
|
ringbuffer_t name; \
|
||||||
|
RingBuffer_Init(&name, Concat(name, Concat(_buffer, __LINE__)), size) \
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2235
Pipe/thread1.txt
Normal file
2235
Pipe/thread1.txt
Normal file
File diff suppressed because it is too large
Load Diff
2852
Pipe/thread2.txt
Normal file
2852
Pipe/thread2.txt
Normal file
File diff suppressed because it is too large
Load Diff
355
Pipe/threads.c
355
Pipe/threads.c
@ -6,103 +6,32 @@
|
|||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
|
|
||||||
|
#define NUMBER_OF_ELEMENTS 1000
|
||||||
|
|
||||||
/* Integrate every element of the signal. */
|
/* Integrate every element of the signal. */
|
||||||
static void increment(pipe_t * const p)
|
static void increment(pipe_t * const pipe)
|
||||||
{
|
{
|
||||||
while (Pipe_isFilled(p))
|
uint8_t check = 1;
|
||||||
|
while (Pipe_IsFilled(pipe))
|
||||||
{
|
{
|
||||||
uint32_t item = Pipe_Read(p);
|
uint32_t item = Pipe_Read(pipe);
|
||||||
item++;
|
|
||||||
Pipe_Write(p, item);
|
// do something
|
||||||
|
|
||||||
|
Pipe_Write(pipe, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI Thread1(LPVOID lpParam)
|
||||||
/* Print the signal. */
|
|
||||||
static void write_to_file1(pipe_t * const pipe)
|
|
||||||
{
|
|
||||||
HANDLE hFile;
|
|
||||||
char DataBuffer[128];
|
|
||||||
DWORD dwBytesWritten = 0;
|
|
||||||
|
|
||||||
hFile = CreateFile("thread1.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
while (Pipe_isFilled(pipe))
|
|
||||||
{
|
|
||||||
sprintf_s(DataBuffer, 128, "%d\r\n", Pipe_Read(pipe));
|
|
||||||
WriteFile(hFile, DataBuffer, (DWORD)strlen(DataBuffer), &dwBytesWritten, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_to_file2(pipe_t * const pipe)
|
|
||||||
{
|
|
||||||
HANDLE hFile;
|
|
||||||
char DataBuffer[128];
|
|
||||||
DWORD dwBytesWritten = 0;
|
|
||||||
|
|
||||||
hFile = CreateFile("thread2.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
while (Pipe_isFilled(pipe))
|
|
||||||
{
|
|
||||||
sprintf_s(DataBuffer, 128, "%d\r\n", Pipe_Read(pipe));
|
|
||||||
WriteFile(hFile, DataBuffer, (DWORD)strlen(DataBuffer), &dwBytesWritten, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI incrementThread1(LPVOID lpParam)
|
|
||||||
{
|
|
||||||
pipe_t * pipe = (pipe_t *)lpParam;
|
|
||||||
LARGE_INTEGER time;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Generate input */
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
|
|
||||||
increment(pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI incrementThread2(LPVOID lpParam)
|
|
||||||
{
|
|
||||||
pipe_t * pipe = (pipe_t *)lpParam;
|
|
||||||
LARGE_INTEGER time;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Generate input */
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
QueryPerformanceCounter(&time);
|
|
||||||
Pipe_Insert(pipe, (uint32_t)time.u.LowPart);
|
|
||||||
|
|
||||||
increment(pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI incrementThread3(LPVOID lpParam)
|
|
||||||
{
|
{
|
||||||
pipe_t * pipe = (pipe_t *)lpParam;
|
pipe_t * pipe = (pipe_t *)lpParam;
|
||||||
|
|
||||||
while (1)
|
/* Generate input */
|
||||||
{
|
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
|
||||||
increment(pipe);
|
Pipe_Insert(pipe, 42);
|
||||||
}
|
increment(pipe);
|
||||||
|
|
||||||
|
Pipe_Write(pipe, UINT32_MAX);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -110,50 +39,242 @@ DWORD WINAPI incrementThread3(LPVOID lpParam)
|
|||||||
DWORD WINAPI Thread2(LPVOID lpParam)
|
DWORD WINAPI Thread2(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
pipe_t * pipe = (pipe_t *)lpParam;
|
pipe_t * pipe = (pipe_t *)lpParam;
|
||||||
write_to_file2(pipe);
|
|
||||||
|
/* Generate input */
|
||||||
|
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
|
||||||
|
Pipe_Insert(pipe, 23);
|
||||||
|
increment(pipe);
|
||||||
|
|
||||||
|
Pipe_Write(pipe, UINT32_MAX);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI Thread1(LPVOID lpParam)
|
DWORD WINAPI Thread3(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
pipe_t * pipe = (pipe_t *)lpParam;
|
pipe_t * pipe = (pipe_t *)lpParam;
|
||||||
write_to_file1(pipe);
|
uint32_t item = 0;
|
||||||
|
uint8_t check = 1;
|
||||||
|
uint8_t symbol_counter = 0;
|
||||||
|
|
||||||
|
while (symbol_counter < 2)
|
||||||
|
{
|
||||||
|
while (Pipe_IsFilled(pipe))
|
||||||
|
{
|
||||||
|
item = Pipe_Read(pipe);
|
||||||
|
|
||||||
|
if (item == UINT32_MAX)
|
||||||
|
{
|
||||||
|
symbol_counter++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item != 42 && item != 23)
|
||||||
|
printf("failed\n");
|
||||||
|
|
||||||
|
Pipe_Write(pipe, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pipe_Write(pipe, UINT32_MAX);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log(pipe_t * const source, pipe_t * const target, uint32_t element) {}
|
DWORD WINAPI Thread4(LPVOID lpParam)
|
||||||
|
|
||||||
void threads(void)
|
|
||||||
{
|
{
|
||||||
/* Create pipes and connect them */
|
pipe_t * pipe = (pipe_t *)lpParam;
|
||||||
Pipe_Create(increment_pipe1, 4, 1, NULL, log);
|
uint32_t item = 0;
|
||||||
Pipe_Create(increment_pipe2, 4, 1, NULL, log);
|
uint8_t check = 1;
|
||||||
Pipe_Create(increment_pipe3, 8, 2, NULL, log);
|
|
||||||
Pipe_Create(write_to_file1_pipe, 8, 1, NULL, log);
|
while (item != UINT32_MAX)
|
||||||
Pipe_Create(write_to_file2_pipe, 8, 1, NULL, log);
|
{
|
||||||
|
while (Pipe_IsFilled(pipe))
|
||||||
|
{
|
||||||
|
item = Pipe_Read(pipe);
|
||||||
|
|
||||||
Pipe_Connect(&increment_pipe1, &increment_pipe3);
|
if (item == UINT32_MAX)
|
||||||
Pipe_Connect(&increment_pipe2, &increment_pipe3);
|
break;
|
||||||
Pipe_Connect(&increment_pipe3, &write_to_file1_pipe);
|
|
||||||
Pipe_Connect(&increment_pipe3, &write_to_file2_pipe);
|
|
||||||
|
|
||||||
/* Create Threads */
|
if (item != 42 && item != 23)
|
||||||
CreateThread(NULL, 0, incrementThread1, &increment_pipe1, 0, NULL);
|
printf("failed\n");
|
||||||
CreateThread(NULL, 0, incrementThread2, &increment_pipe2, 0, NULL);
|
|
||||||
CreateThread(NULL, 0, incrementThread3, &increment_pipe3, 0, NULL);
|
|
||||||
|
|
||||||
HANDLE thread1Handle, thread2Handle;
|
Pipe_Write(pipe, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thread1Handle = CreateThread(NULL, 0, Thread1, &write_to_file1_pipe, 0, NULL);
|
Pipe_Write(pipe, UINT32_MAX);
|
||||||
thread2Handle = CreateThread(NULL, 0, Thread2, &write_to_file2_pipe, 0, NULL);
|
|
||||||
|
|
||||||
HANDLE threadHandles[] = { thread1Handle, thread2Handle };
|
|
||||||
WaitForMultipleObjects(2, threadHandles, TRUE, INFINITE);
|
|
||||||
|
|
||||||
CloseHandle(thread1Handle);
|
|
||||||
CloseHandle(thread2Handle);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI Thread5(LPVOID lpParam)
|
||||||
|
{
|
||||||
|
pipe_t * pipe = (pipe_t *)lpParam;
|
||||||
|
uint32_t item = 0;
|
||||||
|
uint8_t check = 1;
|
||||||
|
|
||||||
|
while (item != UINT32_MAX)
|
||||||
|
{
|
||||||
|
while (Pipe_IsFilled(pipe))
|
||||||
|
{
|
||||||
|
item = Pipe_Read(pipe);
|
||||||
|
if (item == 0 || item > 102)
|
||||||
|
{
|
||||||
|
check = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == UINT32_MAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Pipe_Write(pipe, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pipe_Write(pipe, UINT32_MAX);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Run_Threads(pipe_t * pipe1, pipe_t * pipe2, pipe_t * pipe3, pipe_t * pipe4, pipe_t * pipe5)
|
||||||
|
{
|
||||||
|
/* Create Threads */
|
||||||
|
HANDLE threadHandles[5];
|
||||||
|
|
||||||
|
threadHandles[0] = CreateThread(NULL, 0, Thread1, pipe1, 0, NULL);
|
||||||
|
threadHandles[1] = CreateThread(NULL, 0, Thread2, pipe2, 0, NULL);
|
||||||
|
threadHandles[2] = CreateThread(NULL, 0, Thread3, pipe3, 0, NULL);
|
||||||
|
threadHandles[3] = CreateThread(NULL, 0, Thread4, pipe4, 0, NULL);
|
||||||
|
threadHandles[4] = CreateThread(NULL, 0, Thread5, pipe5, 0, NULL);
|
||||||
|
|
||||||
|
WaitForMultipleObjects(5, threadHandles, TRUE, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(threadHandles[0]);
|
||||||
|
CloseHandle(threadHandles[1]);
|
||||||
|
CloseHandle(threadHandles[2]);
|
||||||
|
CloseHandle(threadHandles[3]);
|
||||||
|
CloseHandle(threadHandles[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ringbuffer_valid_and_equal(ringbuffer_t * rb1, ringbuffer_t * rb2)
|
||||||
|
{
|
||||||
|
//char DataBuffer[128];
|
||||||
|
//DWORD dwBytesWritten;
|
||||||
|
|
||||||
|
uint32_t element1 = 0;
|
||||||
|
uint32_t element2 = 0;
|
||||||
|
uint32_t element_42_counter = 0;
|
||||||
|
uint32_t element_23_counter = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
element1 = RingBuffer_Read(rb1);
|
||||||
|
element2 = RingBuffer_Read(rb2);
|
||||||
|
|
||||||
|
if (element1 != element2)
|
||||||
|
printf("Elements unequal!\n");
|
||||||
|
|
||||||
|
if (element1 == UINT32_MAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (element1 == 42)
|
||||||
|
{
|
||||||
|
element_42_counter++;
|
||||||
|
//sprintf_s(DataBuffer, 128, "%u - %u\r\n", element1, element_42_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element1 == 23)
|
||||||
|
{
|
||||||
|
element_23_counter++;
|
||||||
|
//sprintf_s(DataBuffer, 128, "%u - %u\r\n", element1, element_23_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//WriteFile(h, DataBuffer, (DWORD)strlen(DataBuffer), &dwBytesWritten, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((element_42_counter != element_23_counter) || (element_42_counter != NUMBER_OF_ELEMENTS))
|
||||||
|
{
|
||||||
|
printf("error!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log(pipe_t * const source, pipe_t * const target, uint32_t element)
|
||||||
|
{
|
||||||
|
/*wchar_t text[64];
|
||||||
|
swprintf_s(text, 64, L"%s: %d\n", source->name, element);
|
||||||
|
OutputDebugStringW(text);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void threads(uint32_t loops)
|
||||||
|
{
|
||||||
|
/* Create pipes and connect them */
|
||||||
|
Pipe_Create(increment_pipe1, 1, 1, NULL, log);
|
||||||
|
Pipe_Create(increment_pipe2, 1, 1, NULL, log);
|
||||||
|
Pipe_Create(increment_pipe3, 2, 2, NULL, log);
|
||||||
|
Pipe_Create(increment_pipe4, 1, 1, NULL, log);
|
||||||
|
Pipe_Create(increment_pipe5, 1, 1, NULL, log);
|
||||||
|
Pipe_Create(check_pipe1, 1, 1, NULL, log);
|
||||||
|
Pipe_Create(check_pipe2, 1, 1, NULL, log);
|
||||||
|
|
||||||
|
Pipe_CreateInputBuffer(increment_pipe1, NUMBER_OF_ELEMENTS+2);
|
||||||
|
Pipe_CreateInputBuffer(increment_pipe2, NUMBER_OF_ELEMENTS+2);
|
||||||
|
|
||||||
|
Pipe_CreateConnection(increment_pipe1, increment_pipe3, NUMBER_OF_ELEMENTS+2);
|
||||||
|
Pipe_CreateConnection(increment_pipe2, increment_pipe3, NUMBER_OF_ELEMENTS+2);
|
||||||
|
Pipe_CreateConnection(increment_pipe3, increment_pipe4, NUMBER_OF_ELEMENTS * 2 + 2);
|
||||||
|
Pipe_CreateConnection(increment_pipe3, increment_pipe5, NUMBER_OF_ELEMENTS * 2 + 2);
|
||||||
|
Pipe_CreateConnection(increment_pipe4, check_pipe1, NUMBER_OF_ELEMENTS * 2 + 2);
|
||||||
|
Pipe_CreateConnection(increment_pipe5, check_pipe2, NUMBER_OF_ELEMENTS * 2 + 2);
|
||||||
|
|
||||||
|
//HANDLE hFile;
|
||||||
|
//hFile = CreateFile("buffer.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
SYSTEMTIME local_time;
|
||||||
|
GetLocalTime(&local_time);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("Starting Thread Test\n");
|
||||||
|
printf("at %02d/%02d/%02d %02d:%02d:%02d\n", local_time.wYear, local_time.wMonth, local_time.wDay, local_time.wHour, local_time.wMinute, local_time.wSecond);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
LARGE_INTEGER Frequency;
|
||||||
|
LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
|
||||||
|
QueryPerformanceFrequency(&Frequency);
|
||||||
|
QueryPerformanceCounter(&StartingTime);
|
||||||
|
|
||||||
|
uint32_t success_counter = 0;
|
||||||
|
for (int i = 0; i < loops; i++)
|
||||||
|
{
|
||||||
|
Run_Threads(&increment_pipe1, &increment_pipe2, &increment_pipe3, &increment_pipe4, &increment_pipe5);
|
||||||
|
|
||||||
|
//if (ringbuffer_valid_and_equal(check_pipe1.input_connector->connection[0], check_pipe2.input_connector->connection[0], hFile))
|
||||||
|
if (ringbuffer_valid_and_equal(check_pipe1.input_connector->connection[0], check_pipe2.input_connector->connection[0]))
|
||||||
|
success_counter++;
|
||||||
|
}
|
||||||
|
QueryPerformanceCounter(&EndingTime);
|
||||||
|
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
|
||||||
|
ElapsedMicroseconds.QuadPart *= 1000000;
|
||||||
|
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
|
||||||
|
int seconds = ElapsedMicroseconds.QuadPart / 1000000;
|
||||||
|
|
||||||
|
int hours = seconds / 3600;
|
||||||
|
int minutes = (seconds - (hours * 3600)) / 60;
|
||||||
|
seconds = seconds - (minutes * 60);
|
||||||
|
|
||||||
|
printf("Loops: %d\n", loops);
|
||||||
|
printf("Successfull: %d\n", success_counter);
|
||||||
|
printf("Failed: %d\n", loops - success_counter);
|
||||||
|
printf("Count of Concurrent Data Operations: %d\n", 2 * NUMBER_OF_ELEMENTS * loops);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
GetLocalTime(&local_time);
|
||||||
|
printf("Test finished\n");
|
||||||
|
printf("at %02d/%02d/%02d %02d:%02d:%02d\n", local_time.wYear, local_time.wMonth, local_time.wDay, local_time.wHour, local_time.wMinute, local_time.wSecond);
|
||||||
|
printf("Elapsed time: %02d:%02d:%02d", hours, minutes, seconds);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
//CloseHandle(hFile);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user