diff --git a/Pipe/main.c b/Pipe/main.c index 5fa070a..2c530f5 100644 --- a/Pipe/main.c +++ b/Pipe/main.c @@ -1,8 +1,15 @@ #include #include +#include +#include + #include "ringbuffer.h" #include "pipe.h" +#ifdef _MSC_VER + #define inline __inline +#endif + /* Integrate every element of the signal. */ void increment(pipe_t * const p) { @@ -90,13 +97,86 @@ void log(pipe_t * const source, pipe_t * const target, uint32_t element) printf("%s -> %d -> %s(%d)\n", source->name, element, target->name, *((uint32_t*)target->state)); } + +#define BUF_SIZE 255 + +void DisplayMessage(HANDLE hScreen, + char *ThreadName, int Data, int Count) +{ + + TCHAR msgBuf[BUF_SIZE]; + size_t cchStringSize; + DWORD dwChars; + + // Print message using thread-safe functions. + StringCchPrintf(msgBuf, BUF_SIZE, + TEXT("Executing iteration %02d of %s" + " having data = %02d \n"), + Count, ThreadName, Data); + StringCchLength(msgBuf, BUF_SIZE, &cchStringSize); + WriteConsole(hScreen, msgBuf, cchStringSize, + &dwChars, NULL); +} + +DWORD WINAPI Thread_no_2(LPVOID lpParam) +{ + + int Data = 0; + int count = 0; + HANDLE hStdout = NULL; + + // Get Handle To screen. + // Else how will we print? + if ((hStdout = + GetStdHandle(STD_OUTPUT_HANDLE)) + == INVALID_HANDLE_VALUE) + return 1; + + // Cast the parameter to the correct + // data type passed by callee i.e main() in our case. + Data = *((int*)lpParam); + + for (count = 0; count <= 4; count++) + { + DisplayMessage(hStdout, "Thread_no_1", Data, count); + } + + return 0; +} + +DWORD WINAPI Thread_no_1(LPVOID lpParam) +{ + + int Data = 0; + int count = 0; + HANDLE hStdout = NULL; + + // Get Handle To screen. + // Else how will we print? + if ((hStdout = + GetStdHandle(STD_OUTPUT_HANDLE)) + == INVALID_HANDLE_VALUE) + return 1; + + // Cast the parameter to the correct + // data type passed by callee i.e main() in our case. + Data = *((int*)lpParam); + + for (count = 0; count <= 4; count++) + { + DisplayMessage(hStdout, "Thread_no_2", Data, count); + } + + return 0; +} + int main(void) { uint32_t counter = 0; /* Create pipes and connect them */ - Pipe_Create(increment_pipe, 4, 1, NULL, log); - Pipe_Create(square_pipe, 4, 1, NULL, log); + Pipe_Create(increment_pipe, 4, 1, NULL, NULL); + Pipe_Create(square_pipe, 4, 1, NULL, NULL); Pipe_Create(integrate_pipe, 8, 2, &counter, log); Pipe_Create(sum_pipe, 8, 1, NULL, log); Pipe_Create(average_pipe, 8, 1, NULL, log); @@ -109,6 +189,26 @@ int main(void) Pipe_Connect(&sum_pipe, &print_pipe); Pipe_Connect(&average_pipe, &print_pipe); + /* Create Threads */ + int Data_Of_Thread_1 = 1; + int Data_Of_Thread_2 = 2; + HANDLE Handle_Of_Thread_1 = 0; + HANDLE Handle_Of_Thread_2 = 0; + + Handle_Of_Thread_1 = CreateThread(NULL, 0, Thread_no_1, &Data_Of_Thread_1, 0, NULL); + if (Handle_Of_Thread_1 == NULL) + ExitProcess(Data_Of_Thread_1); + + Handle_Of_Thread_2 = CreateThread(NULL, 0, Thread_no_2, &Data_Of_Thread_2, 0, NULL); + if (Handle_Of_Thread_2 == NULL) + ExitProcess(Data_Of_Thread_2); + + HANDLE Array_Of_Thread_Handles[] = { Handle_Of_Thread_1, Handle_Of_Thread_1 }; + WaitForMultipleObjects(3, Array_Of_Thread_Handles, TRUE, INFINITE); + + CloseHandle(Handle_Of_Thread_1); + CloseHandle(Handle_Of_Thread_2); + /* Generate input */ Pipe_Insert(&increment_pipe, 1); Pipe_Insert(&increment_pipe, 3); diff --git a/Pipe/pipe.h b/Pipe/pipe.h index f93eccf..df127ed 100644 --- a/Pipe/pipe.h +++ b/Pipe/pipe.h @@ -5,7 +5,9 @@ #include "ringbuffer.h" /* microsoft specific */ -#define inline __inline +#ifdef _MSC_VER + #define inline __inline +#endif /* number of connections */ #define PIPE_NUMBER_OF_CONNECTIONS 4 @@ -22,71 +24,6 @@ typedef struct pipe_tt } pipe_t; -/***************************************/ -/* Functions to construct pipe system. */ -/***************************************/ - -#define Concat2(a, b) a ## b -#define Concat(a, b) Concat2(a, b) -#define SizeOfArray(arg) ( sizeof(arg) / sizeof(arg[0]) ) - -/* -Macro for the creation of a pipe. -Automates the creation of a ring buffer and the pipe. -arg_name is the variable name and string name of the pipe. -arg_size is the ring buffer size in bytes. -arg_conn_count is the number of outgoing connections. -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. -*/ -#define Pipe_Create(arg_name, arg_size, arg_conn_count, arg_state, arg_log) \ -static uint32_t Concat(arg_name, Concat(_buffer, __LINE__))[arg_size]; \ -ringbuffer_t arg_name ## _rb; \ -RingBuffer_InitFromArray(&arg_name ## _rb, Concat(arg_name, Concat(_buffer, __LINE__)), arg_size); \ -pipe_t arg_name; \ -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. -A Ringbuffer is needed to store elements from other pipes. -A State (NULL if function has no state) for the function using the pipe. -A Name and a logging function are usefull to track the dataflow. -*/ -static inline void Pipe_Init( - pipe_t * const pipe, - ringbuffer_t * const input, - pipe_t ** pipe_connections, - uint32_t connection_max, - void * state, - char * const name, - void(*log_function)(struct pipe_tt * source, struct pipe_tt * target, uint32_t element) - ) -{ - pipe->input = input; - 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->log_function = log_function; -} - -/* Connect two pipes. Pipe a sends elements to pipe b. */ -static inline void Pipe_Connect(pipe_t * const source, pipe_t * const target) -{ - if (source->connection_count < source->connection_max) - { - source->connection[source->connection_count] = target; - source->connection_count++; - } -} - - /*******************************************/ /* Functions to work with the pipe system. */ /*******************************************/ @@ -140,4 +77,92 @@ static inline uint8_t Pipe_isFull(const pipe_t * pipe) return RingBuffer_IsFull(pipe->input); } +/* +Default Logging function. +Shall be set by user. +*/ +static inline void Pipe_Log(pipe_t * const source, pipe_t * const target, uint32_t element) +{ + if (Pipe_isFull(target)) + printf("Error: Pipe %s is full!\n", target->name); + + if (source->state == NULL && target->state == NULL) + printf("%s -> %d -> %s\n", source->name, element, target->name); + 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)); + else if (source->state != NULL) + printf("%s(%d) -> %d -> %s\n", source->name, *((uint32_t*)source->state), element, target->name); + else + printf("%s -> %d -> %s(%d)\n", source->name, element, target->name, *((uint32_t*)target->state)); +} + + +/***************************************/ +/* Functions to construct pipe system. */ +/***************************************/ + +#define Concat2(a, b) a ## b +#define Concat(a, b) Concat2(a, b) +#define SizeOfArray(arg) ( sizeof(arg) / sizeof(arg[0]) ) + +/* +Macro for the creation of a pipe. +Automates the creation of a ring buffer and the pipe. +arg_name is the variable name and string name of the pipe. +arg_size is the ring buffer size in bytes. +arg_conn_count is the number of outgoing connections. +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. +*/ +#define Pipe_Create(arg_name, arg_size, arg_conn_count, arg_state, arg_log) \ +static uint32_t Concat(arg_name, Concat(_buffer, __LINE__))[arg_size]; \ +ringbuffer_t arg_name ## _rb; \ +RingBuffer_InitFromArray(&arg_name ## _rb, Concat(arg_name, Concat(_buffer, __LINE__)), arg_size); \ +pipe_t arg_name; \ +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. +A Ringbuffer is needed to store elements from other pipes. +A State (NULL if function has no state) for the function using the pipe. +A Name and a logging function are usefull to track the dataflow. +*/ +static inline void Pipe_Init( + pipe_t * const pipe, + ringbuffer_t * const input, + pipe_t ** pipe_connections, + uint32_t connection_max, + void * state, + char * const name, + void(*log_function)(struct pipe_tt * source, struct pipe_tt * target, uint32_t element) + ) +{ + pipe->input = input; + 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; + + if (log_function == NULL) + pipe->log_function = Pipe_Log; + else + pipe->log_function = log_function; +} + +/* Connect two pipes. Pipe a sends elements to pipe b. */ +static inline void Pipe_Connect(pipe_t * const source, pipe_t * const target) +{ + if (source->connection_count < source->connection_max) + { + source->connection[source->connection_count] = target; + source->connection_count++; + } +} + #endif diff --git a/Pipe/ringbuffer.h b/Pipe/ringbuffer.h index f7293aa..ec777fc 100644 --- a/Pipe/ringbuffer.h +++ b/Pipe/ringbuffer.h @@ -3,7 +3,9 @@ #include -#define inline __inline +#ifdef _MSC_VER + #define inline __inline +#endif typedef struct { uint32_t * reader;