diff options
Diffstat (limited to 'all_pairs/source/extra.h')
-rw-r--r-- | all_pairs/source/extra.h | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/all_pairs/source/extra.h b/all_pairs/source/extra.h new file mode 100644 index 0000000..bdbd1f5 --- /dev/null +++ b/all_pairs/source/extra.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /** | ||
2 | * Copyright 2019 Sims Hill Osborne and Joshua Bakita | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
5 | * of this software and associated documentation files (the "Software"), to deal | ||
6 | * in the Software without restriction, including without limitation the rights | ||
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
8 | * copies of the Software, and to permit persons to whom the Software is | ||
9 | * furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | **/ | ||
22 | #include <fcntl.h> | ||
23 | #include <limits.h> | ||
24 | #include <semaphore.h> | ||
25 | #include <signal.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <stdio.h> | ||
28 | #include <string.h> | ||
29 | #include <sys/mman.h> | ||
30 | #include <sys/stat.h> | ||
31 | #include <time.h> | ||
32 | #include <unistd.h> | ||
33 | |||
34 | // Benchmarks use SET_UP, START_LOOP, STOP_LOOP, and WRITE_TO_FILE | ||
35 | // These are macros so that we can declare and maintain additional state inside | ||
36 | // the benchmark. | ||
37 | #define SET_UP if (argc < 8) {\ | ||
38 | printf("Usage: %s <name> <runs> <my core> <other core> <other program> <runID> <lockID>", argv[0]);\ | ||
39 | exit(1);\ | ||
40 | }\ | ||
41 | char * thisProgram = argv[1];\ | ||
42 | int maxJobs = atoi(argv[2]);\ | ||
43 | char * thisCore = argv[3];\ | ||
44 | char * otherCore = argv[4];\ | ||
45 | char * otherProgram = argv[5];\ | ||
46 | char * runID = argv[6];\ | ||
47 | int lockID = atoi(argv[7]);\ | ||
48 | struct timespec start, end;\ | ||
49 | int jobsComplete;\ | ||
50 | long * startS = malloc(sizeof(long) *maxJobs);\ | ||
51 | long * startN = malloc(sizeof(long) *maxJobs);\ | ||
52 | long * endS = malloc(sizeof(long) *maxJobs);\ | ||
53 | long * endN = malloc(sizeof(long) *maxJobs);\ | ||
54 | char * bigArray;\ | ||
55 | char fileName[strlen(runID) + 5];\ | ||
56 | strcpy(fileName, runID);\ | ||
57 | strcat(fileName, ".txt");\ | ||
58 | mlockall(MCL_CURRENT || MCL_FUTURE);\ | ||
59 | sem_t *firstSem=sem_open("/firstTacleSem", O_CREAT, 644, 0);\ | ||
60 | if (firstSem == SEM_FAILED) {\ | ||
61 | perror("Error opening/creating first semaphore");\ | ||
62 | exit(1);\ | ||
63 | }\ | ||
64 | sem_t *secondSem=sem_open("/secondTacleSem", O_CREAT, 644, 0);\ | ||
65 | if (secondSem == SEM_FAILED) {\ | ||
66 | perror("Error opening/creating second semaphore");\ | ||
67 | exit(1);\ | ||
68 | }\ | ||
69 | int barrier_file = shm_open("/TacleBarrier", O_CREAT | O_RDWR, 644);\ | ||
70 | if (barrier_file == -1) {\ | ||
71 | perror("Error creating shared memory");\ | ||
72 | exit(1);\ | ||
73 | }\ | ||
74 | /* This sets our shared file to be one byte of '\0'*/ \ | ||
75 | if (ftruncate(barrier_file, 1) == -1) {\ | ||
76 | perror("Error setting size of shared memory");\ | ||
77 | exit(1);\ | ||
78 | }\ | ||
79 | char * barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0);\ | ||
80 | if (barrier == MAP_FAILED) {\ | ||
81 | perror("Error mapping shared memory");\ | ||
82 | exit(1);\ | ||
83 | }\ | ||
84 | int error;\ | ||
85 | int val; | ||
86 | |||
87 | #define SAVE_RESULTS if (jobsComplete > -1){\ | ||
88 | startS[jobsComplete]=start.tv_sec;\ | ||
89 | startN[jobsComplete]=start.tv_nsec;\ | ||
90 | endS[jobsComplete]=end.tv_sec;\ | ||
91 | endN[jobsComplete]=end.tv_nsec;} | ||
92 | |||
93 | #define WRITE_TO_FILE {\ | ||
94 | munlockall();\ | ||
95 | FILE *fp = fopen(fileName, "a");\ | ||
96 | if (fp == NULL) {\ | ||
97 | perror("Error opening file. \n");\ | ||
98 | exit(1);\ | ||
99 | }\ | ||
100 | for(jobsComplete=0; jobsComplete<maxJobs; jobsComplete++){\ | ||
101 | fprintf(fp, "%s %s %s %s %d %ld %ld %ld %ld %s %d \n",\ | ||
102 | thisProgram, otherProgram, thisCore, otherCore, maxJobs,\ | ||
103 | startS[jobsComplete], startN[jobsComplete], endS[jobsComplete], endN[jobsComplete],\ | ||
104 | runID, jobsComplete);\ | ||
105 | }\ | ||
106 | fclose(fp);\ | ||
107 | /* Clean up the barrier synchronization shared memory */\ | ||
108 | munmap(barrier, 1);\ | ||
109 | shm_unlink("/TacleBarrier");\ | ||
110 | free(startS);\ | ||
111 | free(startN);\ | ||
112 | free(endS);\ | ||
113 | free(endN);\ | ||
114 | } | ||
115 | |||
116 | // Call the wbinvld instruction (it's in a kernel module due to it being ring-0) | ||
117 | #define FLUSH_CACHES FILE *fp = fopen("/proc/wbinvd", "r");\ | ||
118 | if (fp == NULL) {\ | ||
119 | perror("Cache flush module interface cannot be opened");\ | ||
120 | exit(1);\ | ||
121 | }\ | ||
122 | char dummy;\ | ||
123 | if (fread(&dummy, 1, 1, fp) == 0) {\ | ||
124 | perror("Unable to access cache flush module interface");\ | ||
125 | exit(1);\ | ||
126 | }\ | ||
127 | fclose(fp); | ||
128 | |||
129 | // These timers should just be aliases to the hardware counters w/ some small adjustments | ||
130 | #define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start); | ||
131 | #define STOP_TIMER clock_gettime(CLOCK_MONOTONIC, &end); | ||
132 | |||
133 | //check value of sem | ||
134 | //if sem=0, unlock | ||
135 | //if sem=1, spin | ||
136 | |||
137 | #define SLEEP nanosleep((const struct timespec[]){{0, 1000000}}, NULL); | ||
138 | |||
139 | #define FIRST_UNLOCK if (lockID == 1) {\ | ||
140 | if (sem_post(secondSem) != 0) {\ | ||
141 | perror("Unable to unlock second semaphore");\ | ||
142 | exit(1);\ | ||
143 | }\ | ||
144 | } \ | ||
145 | else {\ | ||
146 | if (sem_post(firstSem) != 0) {\ | ||
147 | perror("Unable to unlock first semaphore");\ | ||
148 | exit(1);\ | ||
149 | }\ | ||
150 | } \ | ||
151 | |||
152 | #define FIRST_LOCK if (lockID == 1) {\ | ||
153 | if (sem_wait(firstSem) != 0) {\ | ||
154 | perror("Unable to wait on first semaphore");\ | ||
155 | exit(1);\ | ||
156 | }\ | ||
157 | }\ | ||
158 | else {\ | ||
159 | if (sem_wait(secondSem) != 0) {\ | ||
160 | perror("Unable to wait on second semaphore");\ | ||
161 | exit(1);\ | ||
162 | }\ | ||
163 | } | ||
164 | |||
165 | |||
166 | #define SECOND_UNLOCK if (lockID==1){sem_post(fourthSem) ; }\ | ||
167 | else {sem_post(thirdSem) ; } | ||
168 | |||
169 | #define SECOND_LOCK if (lockID==1){sem_wait(thirdSem); }\ | ||
170 | else {sem_wait(fourthSem); } | ||
171 | |||
172 | #define BARRIER_SYNC if (__sync_bool_compare_and_swap(barrier, 0, 1)) {\ | ||
173 | while (!__sync_bool_compare_and_swap(barrier, 0, 0)) {};\ | ||
174 | }\ | ||
175 | else {\ | ||
176 | __sync_bool_compare_and_swap(barrier, 1, 0);\ | ||
177 | } | ||
178 | |||
179 | #define START_LOOP FIRST_UNLOCK FIRST_LOCK FLUSH_CACHES BARRIER_SYNC START_TIMER | ||
180 | #define STOP_LOOP STOP_TIMER SAVE_RESULTS | ||
181 | |||
182 | |||
183 | /* | ||
184 | Intended structure | ||
185 | |||
186 | main | ||
187 | SET_UP | ||
188 | notice that STOP LOOP negates the ++ if outout=0 | ||
189 | for (jobsComplete=-1; jobsComplete<maxJobs; jobsComplete++){ | ||
190 | START_LOOP | ||
191 | tacleInit(); | ||
192 | tacleMain(); | ||
193 | STOP_LOOP | ||
194 | } | ||
195 | WRITE_TO_FILE | ||
196 | tacleReturn | ||
197 | */ | ||