-
Notifications
You must be signed in to change notification settings - Fork 0
/
threadmap.c
112 lines (83 loc) · 2.14 KB
/
threadmap.c
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
/* CS533 Assignment 5
* threadmap.c: Kernel thread -> user thread lookup
*
* To use this file, add the following lines to your scheduler.h:
* extern struct thread * get_current_thread();
* extern void set_current_thread(struct thread*);
* And optionally:
* #define current_thread (get_current_thread())
*
*/
/*********** uncomment this line once you have completed part 2! **************/
#define PART2COMPLETE
/******************************************************************************/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <stdlib.h>
#ifdef PART2COMPLETE
#include <atomic_ops.h>
#endif
#include "scheduler.h"
#define TABLE_SIZE 7
struct mapping {
pid_t kernel_tid;
struct thread * t;
struct mapping * next;
};
struct mapping * table[TABLE_SIZE];
#ifdef PART2COMPLETE
AO_TS_t table_lock = AO_TS_INITIALIZER;
#endif
void set_current_thread(struct thread * t) {
#ifdef PART2COMPLETE
spinlock_lock(&table_lock);
#endif
// get current kernel thread id
pid_t kernel_tid = syscall(SYS_gettid);
// hash kernel tid
int idx = kernel_tid % TABLE_SIZE;
// search for existing mapping
struct mapping * temp = table[idx];
while(temp) {
// if one exists, update it and return
if(temp->kernel_tid == kernel_tid) {
temp->t = t;
#ifdef PART2COMPLETE
spinlock_unlock(&table_lock);
#endif
return;
}
temp = temp->next;
}
// no mapping exists; create a new mapping
temp = malloc(sizeof(struct mapping));
temp->kernel_tid = kernel_tid;
temp->t = t;
temp->next = table[idx];
table[idx] = temp;
#ifdef PART2COMPLETE
spinlock_unlock(&table_lock);
#endif
}
struct thread * get_current_thread() {
#ifdef PART2COMPLETE
spinlock_lock(&table_lock);
#endif
pid_t kernel_tid = syscall(SYS_gettid);
int idx = kernel_tid % TABLE_SIZE;
struct thread * ret = NULL;
struct mapping * temp = table[idx];
while(temp) {
if(temp->kernel_tid == kernel_tid) {
ret = temp->t;
break;
}
temp = temp->next;
}
#ifdef PART2COMPLETE
spinlock_unlock(&table_lock);
#endif
return ret;
}