Adds a library with pair of functions to put load on CPU.
[can-benchmark.git] / rtems / gw / libs / load.c
1 /*\r
2 * Implements simple producer/consumer thread pair to cause load on the CPU.\r
3\r
4 * Used in benchmarking the CAN gateway.\r
5 *\r
6 * Co-opted from http://support.dce.felk.cvut.cz/pos/cv3/src/semaphore.html. \r
7 */\r
8 \r
9 #include <stdio.h>\r
10 \r
11 #include <pthread.h>\r
12 #include <semaphore.h>\r
13 \r
14 #include "load.h"\r
15 \r
16 \r
17 static void* produce(void* arg);\r
18 static void* consume(void* arg);\r
19 \r
20 /* semaphores for consumer/producer pair */\r
21 static sem_t produced, consumed;\r
22 /* pthread handles for the loader */\r
23 static pthread_t consumer, producer;\r
24 static int n = 0;\r
25 static char running = 0;\r
26 \r
27 static void* produce(void* arg){\r
28     while (1) {\r
29             sem_wait(&consumed);\r
30             n++;  /* increment n by 1 */\r
31             sem_post(&produced);\r
32             pthread_testcancel();\r
33     }\r
34     return NULL;\r
35 }       \r
36 \r
37 static void* consume(void* arg){\r
38     while (1) {\r
39             sem_wait(&produced);\r
40             n--; /* aaand decrement */\r
41             sem_post(&consumed);\r
42             pthread_testcancel();\r
43     }\r
44     return NULL;\r
45 }\r
46 \r
47 int start_thread_load(){\r
48     if (running == 0){\r
49         printf("Attempting to start load.\n");\r
50         int res;\r
51         running = 1;\r
52         res = sem_init(&consumed, 0, 0);\r
53         if (res < 0){\r
54             printf("Couldn't initialize consumed semaphore.\n");\r
55             return 1;\r
56         }\r
57         res = sem_init(&produced, 0, 1);\r
58         if (res < 0){\r
59             printf("Couldn't initialize produced semaphore.\n");\r
60             return 1;\r
61         }\r
62         \r
63         res = pthread_create(&producer, NULL, produce, NULL);\r
64         if (res < 0){\r
65             printf("Couldn't create producer thread.\n");\r
66             return 1;\r
67         }\r
68         \r
69         res = pthread_create(&consumer, NULL, consume, NULL);\r
70         if (res < 0){\r
71             printf("Couldn't create consumer thread.\n");\r
72             return 1;\r
73         }\r
74     \r
75         pthread_detach(producer);\r
76         pthread_detach(consumer);\r
77         printf("Load started succesfully.\n");\r
78         return 0;\r
79     } else {\r
80         printf("Load is already running.\n");\r
81         return 0;\r
82     }\r
83 }\r
84 \r
85 /*\r
86 * This function stops threads loading the CPU and destroys associated semaphores. \r
87\r
88 * No error handling currently, only tries to report errors.\r
89\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             printf("Failed.\n");\r
98             /* Not sure what to do with error here, will have to figure out later. */\r
99         }\r
100         printf("Attempting to cancel consumer thread.\n");\r
101         res = pthread_cancel(consumer);\r
102         if (res != 0){\r
103             printf("Failed.\n");\r
104         }\r
105         printf("Preparing to destroy semaphores.\n");\r
106         sleep(1);\r
107         sem_destroy(&produced);\r
108         sem_destroy(&consumed);\r
109         running = 0;\r
110         printf("Finished.\n");\r
111         return 0;\r
112     } else {\r
113         printf("Load is not running.\n");\r
114         return 0;\r
115     }\r
116 }