Add const to sharc instrumentation functions
[akaros.git] / kern / include / ivy / sharc.h
1 #include <assert.h>
2 #include <string.h>
3
4 #ifdef IVY_FAST_CHECKS
5   #define SINLINE __attribute__((always_inline))
6 #else
7   #define SINLINE inline
8 #endif
9
10 #define SUNUSED __attribute__((unused))
11
12 #ifndef sasmlinkage
13 #define sasmlinkage __attribute__((regparm(0)))
14 #endif
15
16 #ifndef snoreturn
17 #define snoreturn __attribute__((noreturn))
18 #endif
19
20 typedef struct __ivy_sharC_thread {
21 #define SHARC_MAX_LOCKS 16
22     const void *held_locks[SHARC_MAX_LOCKS];
23     unsigned int max_lock;
24 } sharC_env_t;
25
26 #include <env.h>
27
28 extern int __ivy_checking_on;
29
30 #pragma cilnoremove("sharC_env_init")
31 static SINLINE void sharC_env_init(sharC_env_t *sharC_env) TRUSTED;
32 static SINLINE void sharC_env_init(sharC_env_t *sharC_env)
33 WRITES(sharC_env->max_lock,sharC_env->held_locks)
34 {
35         sharC_env->max_lock = 0;
36         memset(sharC_env->held_locks,0,SHARC_MAX_LOCKS);
37         return;
38 }
39
40 #pragma cilnoremove("__sharc_single_threaded")
41 static SINLINE void __sharc_single_threaded(const void *msg) TRUSTED;
42 static SINLINE void __sharc_single_threaded(const void *msg)
43 {
44         // TODO: how do I know how many threads/cores are running?
45     //assert(1);
46     return;
47 }
48
49
50 #define GET_SHARC_THREAD() current->sharC_env
51
52 #define THREAD_LOCKS(thread,i) (thread.held_locks[(i)])
53 #define THREAD_MAX_LOCK(thread) (thread.max_lock)
54
55 #define THIS_LOCKS(i)        (THREAD_LOCKS(GET_SHARC_THREAD(),(i)))
56 #define THIS_MAX_LOCK        (THREAD_MAX_LOCK(GET_SHARC_THREAD()))
57
58 /*
59  * Locks
60  */
61
62 extern void sasmlinkage snoreturn
63 __sharc_lock_error_noreturn(const void *lck, const void *what,
64                             unsigned int sz, const char *msg);
65
66 extern void sasmlinkage
67 __sharc_lock_error_mayreturn(const void *lck, const void *what,
68                              unsigned int sz, const char *msg);
69
70 extern void sasmlinkage snoreturn
71 __sharc_lock_coerce_error_noreturn(const void *dstlck, const void *srclck,
72                                    const char *msg);
73
74 extern void sasmlinkage
75 __sharc_lock_coerce_error_mayreturn(const void *dstlck, const void *srclck,
76                                     const char *msg);
77
78 #ifdef IVY_FAST_CHECKS
79 #define __sharc_lock_error         __sharc_lock_error_noreturn
80 #define __sharc_lock_coerce_error  __sharc_lock_coerce_error_noreturn
81 #else
82 #define __sharc_lock_error         __sharc_lock_error_mayreturn
83 #define __sharc_lock_coerce_error  __sharc_lock_coerce_error_mayreturn
84 #endif
85
86 /* assumes no double-locking */
87 #pragma cilnoremove("__sharc_add_lock")
88 static SINLINE void __sharc_add_lock(const void *lck) TRUSTED;
89 static SINLINE void __sharc_add_lock(const void *lck)
90 {
91     unsigned int i;
92
93         if (!__ivy_checking_on || !current) return;
94
95     for (i = 0; i <= THIS_MAX_LOCK; i++)
96         if (!THIS_LOCKS(i))
97             break;
98
99     if (i > THIS_MAX_LOCK && THIS_MAX_LOCK < SHARC_MAX_LOCKS)
100             THIS_MAX_LOCK++;
101
102     THIS_LOCKS(i) = lck;
103     return;
104 }
105
106 /* this will be very inefficient if the lock isn't actually held */
107 #pragma cilnoremove("__sharc_rm_lock")
108 static SINLINE void __sharc_rm_lock(const void *lck) TRUSTED;
109 static SINLINE void __sharc_rm_lock(const void *lck)
110 {
111     unsigned int i;
112
113         if (!__ivy_checking_on || !current) return;
114
115     for (i = 0; i <= THIS_MAX_LOCK; i++)
116         if (THIS_LOCKS(i) == lck)
117             break;
118
119     if (i == THIS_MAX_LOCK && THIS_MAX_LOCK > 0)
120             THIS_MAX_LOCK--;
121
122     THIS_LOCKS(i) = (void *)0;
123     return;
124 }
125
126 #pragma cilnoremove("__sharc_chk_lock")
127 static SINLINE void
128 __sharc_chk_lock(const void *lck, const void *what, unsigned int sz,
129                  const char *msg) TRUSTED;
130 static SINLINE void
131 __sharc_chk_lock(const void *lck, const void *what, unsigned int sz,
132                  const char *msg)
133 {
134     unsigned int i;
135
136         // TODO: how do I find how many threads are running?
137     //if (__sharc_num_threads == 1) return;
138
139         if (!__ivy_checking_on || !current) return;
140
141     for (i = 0; i <= THIS_MAX_LOCK; i++)
142         if (THIS_LOCKS(i) == lck)
143             break;
144
145     if (i > THIS_MAX_LOCK) {
146             __sharc_lock_error(lck,what,sz,msg);
147     }
148 }
149
150 #pragma cilnoremove("__sharc_coerce_lock")
151 static SINLINE void
152 __sharc_coerce_lock(const void *dstlck, const void *srclck,
153                     const char *msg) TRUSTED;
154 static SINLINE void
155 __sharc_coerce_lock(const void *dstlck, const void *srclck,
156                     const char *msg)
157 {
158         if (!__ivy_checking_on) return;
159
160     if (dstlck != srclck)
161         __sharc_lock_coerce_error(dstlck,srclck,msg);
162 }
163
164 /*
165  * The sharing cast.
166  *
167  */
168
169 extern void __sharc_group_cast_error(int, void *, void *, char *);
170
171 #pragma cilnoremove("__sharc_check_group_cast")
172 static inline void
173 __sharc_check_group_cast(int hassame, void *srcg, void *src, char *msg) TRUSTED;
174 static inline void
175 __sharc_check_group_cast(int hassame, void *srcg, void *src, char *msg)
176 {
177         int old;
178         if (!__ivy_checking_on) return;
179         old = __ivy_checking_on;
180         __ivy_checking_on = 0;
181         panic("sharc group cast unimplemented");
182         __ivy_checking_on = old;
183 }
184
185
186 extern void __sharc_cast_error(void *addr, unsigned long sz, char *msg);
187
188 #pragma cilnoremove("__sharc_sharing_cast")
189 static SINLINE void *
190 __sharc_sharing_cast(void *addr,void **slot, unsigned int localslot SUNUSED,
191                      unsigned long lo, unsigned long hi,
192                      char *msg) TRUSTED;
193 static SINLINE void *
194 __sharc_sharing_cast(void *addr,void **slot, unsigned int localslot SUNUSED,
195                      unsigned long lo, unsigned long hi,
196                      char *msg)
197 {
198         int old;
199         if (!__ivy_checking_on) return NULL;
200         old = __ivy_checking_on;
201         __ivy_checking_on = 0;
202         panic("sharc sharing cast unimplemented");
203         __ivy_checking_on = old;
204         return NULL;
205 }