]> rtime.felk.cvut.cz Git - can-benchmark.git/blob - rtems/gw/libs/load.c
6afb7a9f5ddf806e394bc4e806a035d40ee727c9
[can-benchmark.git] / rtems / gw / libs / load.c
1 #include <stdio.h>\r
2 \r
3 #include <pthread.h>\r
4 #include <semaphore.h>\r
5 \r
6 #include "load.h"\r
7 \r
8 /* Load function for threads. */\r
9 static void* produce(void* arg);\r
10 static void* consume(void* arg);\r
11 \r
12 /* semaphores for consumer/producer pair */\r
13 static sem_t produced, consumed;\r
14 /* pthread handles for the loader */\r
15 static pthread_t consumer, producer;\r
16 static int n = 0;\r
17 static char running = 0;\r
18 \r
19 static void* produce(void* arg){\r
20     while (1) {\r
21             sem_wait(&consumed);\r
22             n++; \r
23             sem_post(&produced);\r
24             pthread_testcancel();\r
25     }\r
26     return NULL;\r
27 }       \r
28 \r
29 static void* consume(void* arg){\r
30     while (1) {\r
31             sem_wait(&produced);\r
32             n--;\r
33             sem_post(&consumed);\r
34             pthread_testcancel();\r
35     }\r
36     return NULL;\r
37 }\r
38 \r
39 /*\r
40 * This function starts threads loading the CPU and creates associated semaphores. \r
41\r
42 * Has a guard to prevent starting again, before it was stopped.\r
43 *\r
44 * No error handling currently, only tries to report errors.\r
45 */\r
46 int start_thread_load(){\r
47     if (running == 0){\r
48         printf("Attempting to start load.\n");\r
49         int res;\r
50         running = 1;\r
51         res = sem_init(&consumed, 0, 0);\r
52         if (res < 0){\r
53             printf("Couldn't initialize consumed semaphore.\n");\r
54             return 1;\r
55         }\r
56         res = sem_init(&produced, 0, 1);\r
57         if (res < 0){\r
58             printf("Couldn't initialize produced semaphore.\n");\r
59             return 1;\r
60         }\r
61         \r
62         res = pthread_create(&producer, NULL, produce, NULL);\r
63         if (res < 0){\r
64             printf("Couldn't create producer thread.\n");\r
65             return 1;\r
66         }\r
67         \r
68         res = pthread_create(&consumer, NULL, consume, NULL);\r
69         if (res < 0){\r
70             printf("Couldn't create consumer thread.\n");\r
71             return 1;\r
72         }\r
73     \r
74         pthread_detach(producer);\r
75         pthread_detach(consumer);\r
76         printf("Load started succesfully.\n");\r
77         return 0;\r
78     } else {\r
79         printf("Load is already running.\n");\r
80         return 0;\r
81     }\r
82 }\r
83 \r
84 /*\r
85 * This function stops threads loading the CPU and destroys associated semaphores. \r
86 *\r
87 * Has a guard against attempting to stop the threads if they are not running.\r
88\r
89 * No error handling currently, only tries to report errors.\r
90 */\r
91 int end_thread_load(){\r
92     if (running == 1){\r
93         int res;\r
94         printf("Attempting to cancel producer thread.\n");\r
95         res = pthread_cancel(producer);\r
96         if (res != 0){\r
97             /* This means that sending cancel signal has failed... Just returning an error should be enough. */\r
98             /* If we killed the thread, destroying the semaphore would lead to UB. */\r
99             printf("Failed.\n");\r
100             return 1;\r
101         }\r
102 \r
103         printf("Attempting to cancel consumer thread.\n");\r
104         res = pthread_cancel(consumer);\r
105         if (res != 0){\r
106             /* Same here. */\r
107             printf("Failed.\n");\r
108             return 1;\r
109         }\r
110 \r
111         printf("Preparing to destroy semaphores.\n");\r
112         /* Wait a bit so that the threads can get to a cancellation point. */\r
113         sleep(1);\r
114         sem_destroy(&produced);\r
115         sem_destroy(&consumed);\r
116         running = 0;\r
117         printf("Finished.\n");\r
118         return 0;\r
119     } else {\r
120         printf("Load is not running.\n");\r
121         return 0;\r
122     }\r
123 }