-#include <stdio.h>\r
-\r
-#include <pthread.h>\r
-#include <semaphore.h>\r
-\r
-#include "load.h"\r
-\r
-/* Load function for threads. */\r
-static void* produce(void* arg);\r
-static void* consume(void* arg);\r
-\r
-/* semaphores for consumer/producer pair */\r
-static sem_t produced, consumed;\r
-/* pthread handles for the loader */\r
-static pthread_t consumer, producer;\r
-static int n = 0;\r
-static char running = 0;\r
-\r
-static void* produce(void* arg){\r
- while (1) {\r
- sem_wait(&consumed);\r
- n++; \r
- sem_post(&produced);\r
- pthread_testcancel();\r
- }\r
- return NULL;\r
-} \r
-\r
-static void* consume(void* arg){\r
- while (1) {\r
- sem_wait(&produced);\r
- n--;\r
- sem_post(&consumed);\r
- pthread_testcancel();\r
- }\r
- return NULL;\r
-}\r
-\r
-/*\r
-* This function starts threads loading the CPU and creates associated semaphores. \r
-* \r
-* Has a guard to prevent starting again, before it was stopped.\r
-*\r
-* No error handling currently, only tries to report errors.\r
-*/\r
-int start_thread_load(){\r
- if (running == 0){\r
- printf("Attempting to start load.\n");\r
- int res;\r
- running = 1;\r
- res = sem_init(&consumed, 0, 0);\r
- if (res < 0){\r
- printf("Couldn't initialize consumed semaphore.\n");\r
- return 1;\r
- }\r
- res = sem_init(&produced, 0, 1);\r
- if (res < 0){\r
- printf("Couldn't initialize produced semaphore.\n");\r
- return 1;\r
- }\r
- \r
- res = pthread_create(&producer, NULL, produce, NULL);\r
- if (res < 0){\r
- printf("Couldn't create producer thread.\n");\r
- return 1;\r
- }\r
- \r
- res = pthread_create(&consumer, NULL, consume, NULL);\r
- if (res < 0){\r
- printf("Couldn't create consumer thread.\n");\r
- return 1;\r
- }\r
- \r
- pthread_detach(producer);\r
- pthread_detach(consumer);\r
- printf("Load started succesfully.\n");\r
- return 0;\r
- } else {\r
- printf("Load is already running.\n");\r
- return 0;\r
- }\r
-}\r
-\r
-/*\r
-* This function stops threads loading the CPU and destroys associated semaphores. \r
-*\r
-* Has a guard against attempting to stop the threads if they are not running.\r
-* \r
-* No error handling currently, only tries to report errors.\r
-*/\r
-int end_thread_load(){\r
- if (running == 1){\r
- int res;\r
- printf("Attempting to cancel producer thread.\n");\r
- res = pthread_cancel(producer);\r
- if (res != 0){\r
- /* This means that sending cancel signal has failed... Just returning an error should be enough. */\r
- /* If we killed the thread, destroying the semaphore would lead to UB. */\r
- printf("Failed.\n");\r
- return 1;\r
- }\r
-\r
- printf("Attempting to cancel consumer thread.\n");\r
- res = pthread_cancel(consumer);\r
- if (res != 0){\r
- /* Same here. */\r
- printf("Failed.\n");\r
- return 1;\r
- }\r
-\r
- printf("Preparing to destroy semaphores.\n");\r
- /* Wait a bit so that the threads can get to a cancellation point. */\r
- sleep(1);\r
- sem_destroy(&produced);\r
- sem_destroy(&consumed);\r
- running = 0;\r
- printf("Finished.\n");\r
- return 0;\r
- } else {\r
- printf("Load is not running.\n");\r
- return 0;\r
- }\r
+#include <stdio.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "load.h"
+
+/* Load function for threads. */
+static void* produce(void* arg);
+static void* consume(void* arg);
+
+/* semaphores for consumer/producer pair */
+static sem_t produced, consumed;
+/* pthread handles for the loader */
+static pthread_t consumer, producer;
+static int n = 0;
+static char running = 0;
+
+static void* produce(void* arg){
+ while (1) {
+ sem_wait(&consumed);
+ n++;
+ sem_post(&produced);
+ pthread_testcancel();
+ }
+ return NULL;
+}
+
+static void* consume(void* arg){
+ while (1) {
+ sem_wait(&produced);
+ n--;
+ sem_post(&consumed);
+ pthread_testcancel();
+ }
+ return NULL;
+}
+
+/*
+* This function starts threads loading the CPU and creates associated semaphores.
+*
+* Has a guard to prevent starting again, before it was stopped.
+*
+* No error handling currently, only tries to report errors.
+*/
+int start_thread_load(){
+ if (running == 0){
+ printf("Attempting to start load.\n");
+ int res;
+ running = 1;
+ res = sem_init(&consumed, 0, 0);
+ if (res < 0){
+ printf("Couldn't initialize consumed semaphore.\n");
+ return 1;
+ }
+ res = sem_init(&produced, 0, 1);
+ if (res < 0){
+ printf("Couldn't initialize produced semaphore.\n");
+ return 1;
+ }
+
+ res = pthread_create(&producer, NULL, produce, NULL);
+ if (res < 0){
+ printf("Couldn't create producer thread.\n");
+ return 1;
+ }
+
+ res = pthread_create(&consumer, NULL, consume, NULL);
+ if (res < 0){
+ printf("Couldn't create consumer thread.\n");
+ return 1;
+ }
+
+ pthread_detach(producer);
+ pthread_detach(consumer);
+ printf("Load started succesfully.\n");
+ return 0;
+ } else {
+ printf("Load is already running.\n");
+ return 0;
+ }
+}
+
+/*
+* This function stops threads loading the CPU and destroys associated semaphores.
+*
+* Has a guard against attempting to stop the threads if they are not running.
+*
+* No error handling currently, only tries to report errors.
+*/
+int end_thread_load(){
+ if (running == 1){
+ int res;
+ printf("Attempting to cancel producer thread.\n");
+ res = pthread_cancel(producer);
+ if (res != 0){
+ /* This means that sending cancel signal has failed... Just returning an error should be enough. */
+ /* If we killed the thread, destroying the semaphore would lead to UB. */
+ printf("Failed.\n");
+ return 1;
+ }
+
+ printf("Attempting to cancel consumer thread.\n");
+ res = pthread_cancel(consumer);
+ if (res != 0){
+ /* Same here. */
+ printf("Failed.\n");
+ return 1;
+ }
+
+ printf("Preparing to destroy semaphores.\n");
+ /* Wait a bit so that the threads can get to a cancellation point. */
+ sleep(1);
+ sem_destroy(&produced);
+ sem_destroy(&consumed);
+ running = 0;
+ printf("Finished.\n");
+ return 0;
+ } else {
+ printf("Load is not running.\n");
+ return 0;
+ }
}
\ No newline at end of file