-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchess.cpp
More file actions
301 lines (234 loc) · 7.45 KB
/
chess.cpp
File metadata and controls
301 lines (234 loc) · 7.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <dlfcn.h>
#include <map>
#include <stdio.h>
using namespace std;
/* thread statuses*/
#define RUNNING_WITH_LOCK 1; //thread runs and does not need lock
#define RUNNING_NO_LOCK 2; //threads runs and is waiting for lock
#define TERMINATE 3; //thread terminated
int (*original_pthread_create)(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*) = NULL;
int (*original_pthread_join)(pthread_t, void**) = NULL;
int (*original_pthread_mutex_unlock)(pthread_mutex_t*) = NULL;
int (*original_pthread_mutex_lock)(pthread_mutex_t*) = NULL;
static pthread_mutex_t globalLock = PTHREAD_MUTEX_INITIALIZER; //global lock
static pthread_t current = 0;
// PART 2
static int total_sync_point = 0;
static int current_sync_point = 1;
//static int temp_global = 0;
static bool wait = false;
static pthread_t tempthread;
static bool firsttime = true;
static map<pthread_mutex_t*, pthread_t> mutexMap; //maps mutex lock to its value
static map<pthread_t, int> threadMap; //maps thread to its status
static void initialize_original_functions();
static void performSyncPointCheck();
static bool isFirstExecution();
static int getCurrentSyncPoint();
struct Thread_Arg {
void* (*start_routine)(void*);
void* arg;
};
static
void* thread_main(void *arg)
{
struct Thread_Arg thread_arg = *(struct Thread_Arg*)arg;
free(arg);
// spinlock
//while(pthread_equal(pthread_self(),current) == 0) {}
// lock the global lock
original_pthread_mutex_lock(&globalLock);
void* ret = thread_arg.start_routine(thread_arg.arg); //call second thread
// thread stops running
threadMap[pthread_self()] = TERMINATE;
original_pthread_mutex_unlock(&globalLock);
/*PART 2*/
// outputs the total synchronization points to the file syncpoints
int temt;
FILE *ftemp = fopen("syncpoints.txt","r");
fscanf(ftemp,"%d",&temt);
fclose(ftemp);
if (temt == 0) {
//fprintf(stderr,"updating sync points\n");
FILE *output = fopen("syncpoints.txt","w");
fprintf(output,"%d\n",total_sync_point);
fclose(output);
}
current = tempthread;
return ret;
}
extern "C"
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg)
{
initialize_original_functions();
struct Thread_Arg *thread_arg = (struct Thread_Arg*)malloc(sizeof(struct Thread_Arg));
thread_arg->start_routine = start_routine;
thread_arg->arg = arg;
// global lock is locked now (first instance of create a new thread)
if (firsttime) {
threadMap[pthread_self()] = RUNNING_WITH_LOCK;
firsttime = false;
current = pthread_self();
original_pthread_mutex_lock(&globalLock);
}
tempthread = pthread_self();
int ret = original_pthread_create(thread, attr, thread_main, thread_arg);
threadMap[*thread] = RUNNING_NO_LOCK;
fprintf(stderr,"pthread_create\n");
performSyncPointCheck();
return ret;
}
extern "C"
int pthread_join(pthread_t joinee, void **retval)
{
initialize_original_functions();
original_pthread_mutex_unlock(&globalLock);
/* select next available thread to execute */
/* wait till joinee terminates */
int x = TERMINATE;
if (threadMap[joinee] != x)
current = joinee;
wait = true;
//fprintf(stderr,"stuck in thread join :(\n");
while(threadMap[joinee] != x) {}
wait = false;
// temp_global--;
original_pthread_mutex_lock(&globalLock);
return original_pthread_join(joinee, retval);
}
extern "C"
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
initialize_original_functions();
// check if *mutex is held by other threads.
// but it needs to be in the map.
// if mutex is held by other threads
// if thread in map is different from the current thread
if (mutexMap[mutex] != 0)
{
// unlock the global lock first
original_pthread_mutex_unlock(&globalLock);
// select next available thread to execute; ie: find the next thread available to run
current = mutexMap[mutex];
threadMap[current] = RUNNING_WITH_LOCK;
// wait till L is not held by other threads; ie wait till its done running
while(pthread_equal(pthread_self(),current) == 0) {}
// now the running thread is the other one
current = pthread_self();
original_pthread_mutex_lock(&globalLock);
// PART2 sync point - before mutex is locked
fprintf(stderr,"lock1\n");
performSyncPointCheck();
// lock the mutex and change status of thread
mutexMap[mutex] = current;
threadMap[current] = RUNNING_WITH_LOCK;
}
else
{
current = pthread_self();
// PART2 sync point - before mutex is locked
fprintf(stderr,"lock2\n");
performSyncPointCheck();
mutexMap[mutex] = current;
threadMap[current] = RUNNING_WITH_LOCK;
}
return original_pthread_mutex_lock(mutex);
}
extern "C"
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
initialize_original_functions();
// if L belongs to current thread, then UNLOCK(L)
if (pthread_equal(mutexMap[mutex],pthread_self()) != 0) {
fprintf(stderr,"unlock\n");
mutexMap[mutex] = 0;
}
int ret = original_pthread_mutex_unlock(mutex);
performSyncPointCheck();
return ret;
}
extern "C"
int sched_yield(void)
{
// fprintf(stderr,"in yield\n");
original_pthread_mutex_unlock(&globalLock);
// select next available thread to execute
// if there's no other available thread, the calling thread will execute
// if there's another available thread, the other thread should be executed
map<pthread_t,int>::iterator thread_it;
// iterate through each thread in the map
for (thread_it = threadMap.begin() ; thread_it != threadMap.end() && !wait; thread_it++)
{
int x = RUNNING_NO_LOCK;
// check if the thread is running with no lock
if (thread_it->second == x) {
// then let it run instead of the current thread
// threadMap[current] = RUNNING_NO_LOCK;
current = thread_it->first;
threadMap[current] = RUNNING_WITH_LOCK;
break;
}
}
while(pthread_equal(pthread_self(),current) == 0){}
original_pthread_mutex_lock(&globalLock);
return 0;
}
static
void initialize_original_functions()
{
static bool initialized = false;
if (!initialized) {
initialized = true;
original_pthread_create =
(int (*)(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*))dlsym(RTLD_NEXT, "pthread_create");
original_pthread_join =
(int (*)(pthread_t, void**))dlsym(RTLD_NEXT, "pthread_join");
original_pthread_mutex_lock =
(int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_lock");
original_pthread_mutex_unlock =
(int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}
}
static
void performSyncPointCheck()
{
// if its the first execution
if (isFirstExecution())
{
// keep track of synchronization point
total_sync_point++;
}
else
{
// check if the current sync point in the file is the same as the one in the program
if (getCurrentSyncPoint() == current_sync_point++) {
//switchThread();
sched_yield();
fprintf(stderr,"yielded");
}
//current_sync_point++;
}
}
// checks if the current execution is the first execution
static bool isFirstExecution()
{
int temp;
FILE *f = fopen("syncpoints.txt","r");
fscanf(f,"%d",&temp);
fclose(f);
if (temp == 0) return true;
else return false;
}
// get the current sync point from the text file
static int getCurrentSyncPoint()
{
int temp;
FILE *f = fopen("nth-thread.txt","r");
fscanf(f,"%d",&temp);
fclose(f);
return temp;
}