diff --git a/petersons-windows/build.bat b/petersons-windows/build.bat new file mode 100644 index 0000000..4558362 --- /dev/null +++ b/petersons-windows/build.bat @@ -0,0 +1 @@ +../vcbuild.bat main \ No newline at end of file diff --git a/petersons-windows/main.c b/petersons-windows/main.c new file mode 100644 index 0000000..4b97a15 --- /dev/null +++ b/petersons-windows/main.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#define BUFFER_SIZE 10 + +#if !defined(true) && !defined(false) + #define true 1 + #define false 0 +#endif + +volatile int counter = -1; +volatile int buffer[BUFFER_SIZE]; + +volatile int turn; +volatile int flag[2]; + +DWORD WINAPI produce(void* data) { + srand (time(NULL)); + while (true) + { + flag[0] = true; + turn = 1; + //while (counter == BUFFER_SIZE - 1); // make sure the buffer doesn't overflow + while (flag[1] && turn == 1); + if (counter == BUFFER_SIZE - 1) + { + continue; + flag[0] = false; + } + + + buffer[counter + 1] = rand() % 20 + 1; // yes I know rand is not thread safe - I just need a way to demonstrate a producing/consuming problem - using the same number doesn't help. + printf("PRODUCER value = %i counter = %i\n", buffer[counter + 1], counter + 1); + counter++; + flag[0] = false; + + } +} + +DWORD WINAPI consume(void* data) { + while(true) + { + flag[1] = true; + turn = 0; + //while (counter == -1); // make sure there is content to consume + while (flag[0] && turn == 0); + if (counter == -1) // producer hasn't produced + { + flag[1] = false; + continue; + } + if (buffer[counter] == 0) + { + printf("%i\n", buffer[counter]); + printf("Attempting to consume an element that was already consumed counter = %i\n", counter); + exit(1); + } + printf("CONSUMER value = %i counter = %i\n", buffer[counter], counter); + counter--; + buffer[counter] = 0; + flag[1] = false; + } +} + +int main() { + int i; + HANDLE thread1, thread2; + for(i = 0; i < BUFFER_SIZE; i++) + buffer[i] = -1; + flag[0] = true; + flag[1] = true; + + thread1 = CreateThread(NULL, 0, produce, NULL, 0, NULL); + thread2 = CreateThread(NULL, 0, consume, NULL, 0, NULL); + WaitForSingleObject(thread1, 50); + WaitForSingleObject(thread2, 50); +} \ No newline at end of file diff --git a/racecondition-linux/build.sh b/racecondition-linux/build.sh new file mode 100644 index 0000000..e2164d8 --- /dev/null +++ b/racecondition-linux/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +gcc -o main main.c +./main \ No newline at end of file diff --git a/racecondition-linux/main.c b/racecondition-linux/main.c new file mode 100644 index 0000000..3e32031 --- /dev/null +++ b/racecondition-linux/main.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#define BUFFER_SIZE 10 + +volatile int counter = -1; +volatile int buffer[BUFFER_SIZE]; + +void * produce(void* data) { + srand (time(NULL)); + while (1) + { + while (counter == BUFFER_SIZE - 1); + + buffer[counter + 1] = rand() % 20 + 1; // yes I know rand is not thread safe - I just need a way to demonstrate a producing/consuming problem - using the same number doesn't help. + printf("PRODUCER value = %i counter = %i\n", buffer[counter + 1], counter + 1); + counter++; + } +} + +void * consume(void* data) { + while(1) + { + while (counter == -1); + if (buffer[counter] == 0) + { + printf("%i\n", buffer[counter]); + printf("Attempting to consume an element that was already consumed counter = %i\n", counter); + exit(1); + } + printf("CONSUMER value = %i counter = %i\n", buffer[counter], counter); + buffer[counter] = 0; + counter--; + } +} + +int main() { + int i; + pthread_t thread1, thread2; + int iret1, iret2; + for(i = 0; i < BUFFER_SIZE; i++) + buffer[i] = -1; + iret1 = pthread_create( &thread1, NULL, produce, NULL); + iret2 = pthread_create( &thread2, NULL, consume, NULL); + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + + return 0; + +} \ No newline at end of file diff --git a/racecondition-windows/build.bat b/racecondition-windows/build.bat new file mode 100644 index 0000000..4558362 --- /dev/null +++ b/racecondition-windows/build.bat @@ -0,0 +1 @@ +../vcbuild.bat main \ No newline at end of file diff --git a/racecondition-windows/main.c b/racecondition-windows/main.c new file mode 100644 index 0000000..dee3711 --- /dev/null +++ b/racecondition-windows/main.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#define BUFFER_SIZE 10 + +volatile int counter = -1; +volatile int buffer[BUFFER_SIZE]; + +DWORD WINAPI produce(void* data) { + srand (time(NULL)); + while (1) + { + while (counter == BUFFER_SIZE - 1); + + buffer[counter + 1] = rand() % 20 + 1; // yes I know rand is not thread safe - I just need a way to demonstrate a producing/consuming problem - using the same number doesn't help. + printf("PRODUCER value = %i counter = %i\n", buffer[counter + 1], counter + 1); + counter++; + } +} + +DWORD WINAPI consume(void* data) { + while(1) + { + while (counter == -1); + if (buffer[counter] == 0) + { + printf("%i\n", buffer[counter]); + printf("Attempting to consume an element that was already consumed counter = %i\n", counter); + exit(1); + } + printf("CONSUMER value = %i counter = %i\n", buffer[counter], counter); + buffer[counter] = 0; + counter--; + } +} + +int main() { + int i; + HANDLE thread1, thread2; + for(i = 0; i < BUFFER_SIZE; i++) + buffer[i] = -1; + thread1 = CreateThread(NULL, 0, produce, NULL, 0, NULL); + thread2 = CreateThread(NULL, 0, consume, NULL, 0, NULL); + WaitForSingleObject(thread1, INFINITE); + WaitForSingleObject(thread2, INFINITE); +} \ No newline at end of file