Rev 2309 | Rev 2330 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2309 | Rev 2315 | ||
|---|---|---|---|
| Line 93... | Line 93... | ||
| 93 | { |
93 | { |
| 94 | #ifdef CONFIG_SMP |
94 | #ifdef CONFIG_SMP |
| 95 | waitq_t *wq = malloc(sizeof(waitq_t),0); |
95 | waitq_t *wq = malloc(sizeof(waitq_t),0); |
| 96 | waitq_initialize(wq); |
96 | waitq_initialize(wq); |
| 97 | rcu_sync_callback(&rcu_synchronize_callback_function, wq); |
97 | rcu_sync_callback(&rcu_synchronize_callback_function, wq); |
| 98 | printf("going to sleep\n"); |
98 | printf("going to sleep, tlock:%x, wqlock:%x\n", THREAD->lock.val, wq->lock.val); |
| 99 | waitq_sleep(wq); |
99 | waitq_sleep(wq); |
| 100 | printf("woken up\n"); |
100 | printf("woken up\n"); |
| - | 101 | free(wq); |
|
| 101 | #endif |
102 | #endif |
| 102 | } |
103 | } |
| 103 | 104 | ||
| 104 | #ifdef CONFIG_SMP |
105 | #ifdef CONFIG_SMP |
| 105 | void rcu_synchronize_callback_function(void* waitq) |
106 | void rcu_synchronize_callback_function(void* waitq) |
| 106 | { |
107 | { |
| - | 108 | printf("waking up, wq:%x, wq->head:%x, next:%x, tlock:%x, wqlock:%x\n", |
|
| - | 109 | waitq, |
|
| 107 | printf("waking up\n"); |
110 | ((waitq_t*)waitq)->head, |
| - | 111 | ((link_t)((waitq_t*)waitq)->head).next, |
|
| - | 112 | THREAD->lock.val, |
|
| - | 113 | ((waitq_t*)waitq)->lock.val ); |
|
| 108 | waitq_wakeup(((waitq_t*)waitq), WAKEUP_ALL_INC_MISSED); |
114 | waitq_wakeup(((waitq_t*)waitq), WAKEUP_ALL); |
| 109 | } |
115 | } |
| 110 | #endif |
116 | #endif |
| 111 | 117 | ||
| 112 | void rcu_sync_callback(void (*func)(void* data), void* data) |
118 | void rcu_sync_callback(void (*func)(void* data), void* data) |
| 113 | { |
119 | { |
| Line 118... | Line 124... | ||
| 118 | rcu_callback_list_t *rd; |
124 | rcu_callback_list_t *rd; |
| 119 | rd = malloc(sizeof(rcu_callback_list_t), 0); |
125 | rd = malloc(sizeof(rcu_callback_list_t), 0); |
| 120 | rd->func = func; |
126 | rd->func = func; |
| 121 | rd->data = data; |
127 | rd->data = data; |
| 122 | rd->next = NULL; |
128 | rd->next = NULL; |
| - | 129 | ||
| 123 | printf("synccallback locking \n"); |
130 | printf("synccallback locking \n"); |
| 124 | spinlock_lock(&rcu_global_lock); |
131 | spinlock_lock(&rcu_global_lock); |
| - | 132 | ||
| 125 | rd->next = _rcu_global->next_batch; |
133 | rd->next = _rcu_global->next_batch; |
| 126 | _rcu_global->next_batch = rd; |
134 | _rcu_global->next_batch = rd; |
| 127 | 135 | ||
| 128 | if (_rcu_global->current_batch == NULL) { |
136 | if (_rcu_global->current_batch == NULL) { |
| 129 | _rcu_global->current_batch = _rcu_global->next_batch; |
137 | _rcu_global->current_batch = _rcu_global->next_batch; |
| Line 169... | Line 177... | ||
| 169 | //append the current list to done list |
177 | //append the current list to done list |
| 170 | rd->next = _rcu_global->current_batch; |
178 | rd->next = _rcu_global->current_batch; |
| 171 | } else |
179 | } else |
| 172 | _rcu_global->done_batch = _rcu_global->current_batch; |
180 | _rcu_global->done_batch = _rcu_global->current_batch; |
| 173 | printf("setting callback %x as done\n",&_rcu_global->current_batch->func); |
181 | printf("setting callback %x as done\n",&_rcu_global->current_batch->func); |
| - | 182 | _rcu_global->current_batch = _rcu_global->next_batch; |
|
| 174 | _rcu_global->current_batch = NULL; |
183 | _rcu_global->next_batch = NULL; |
| 175 | } |
184 | #ifdef CONFIG_SMP |
| 176 | 185 | ||
| 177 | _rcu_global->current_batch = _rcu_global->next_batch; |
186 | for (i=0;i<config.cpu_count;i++) |
| 178 | _rcu_global->next_batch = NULL; |
187 | _rcu_global->cpu_mask[i]=false; |
| - | 188 | #endif |
|
| - | 189 | //we've surely passed the quiescent point just by running this method |
|
| - | 190 | rcu_passQS(); |
|
| - | 191 | } |
|
| 179 | 192 | ||
| 180 | if (_rcu_global->current_batch == NULL) { |
- | |
| 181 | //there are no rcu callbacks registered, there is no need to monitor QS |
- | |
| 182 | printf("tasklet idle disabling \n"); |
- | |
| 183 | // tasklet_disable(rcu_tasklet_desc); |
- | |
| 184 | spinlock_unlock(&rcu_global_lock); |
- | |
| 185 | } else |
- | |
| 186 | spinlock_unlock(&rcu_global_lock); |
193 | spinlock_unlock(&rcu_global_lock); |
| 187 | printf("tasklet unlocking \n"); |
194 | printf("tasklet unlocking \n"); |
| 188 | } |
195 | } |
| 189 | 196 | ||
| 190 | inline void rcu_passQS(void) |
197 | inline void rcu_passQS(void) |
| 191 | { |
198 | { |
| Line 197... | Line 204... | ||
| 197 | void rcu_run_callbacks(void) |
204 | void rcu_run_callbacks(void) |
| 198 | { |
205 | { |
| 199 | rcu_callback_list_t* rd; |
206 | rcu_callback_list_t* rd; |
| 200 | rcu_passQS(); |
207 | rcu_passQS(); |
| 201 | if (_rcu_global->done_batch) { |
208 | if (_rcu_global->done_batch) { |
| 202 | printf("."); |
209 | printf("run callbacks locking\n"); |
| 203 | spinlock_lock(&rcu_global_lock); |
210 | spinlock_lock(&rcu_global_lock); |
| 204 | for (rd = _rcu_global->done_batch; rd; rd=rd->next) { |
211 | rd = _rcu_global->done_batch; |
| - | 212 | _rcu_global->done_batch = NULL; |
|
| - | 213 | spinlock_unlock(&rcu_global_lock); |
|
| - | 214 | printf("run callbacks unlocking\n"); |
|
| - | 215 | for (; rd; rd=rd->next) { |
|
| 205 | printf("calling %x \n",&rd->func); |
216 | printf("calling %x \n",&rd->func); |
| 206 | rd->func(&rd->data); |
217 | rd->func(&rd->data); |
| 207 | } |
218 | } |
| 208 | _rcu_global->done_batch = NULL; |
- | |
| 209 | spinlock_unlock(&rcu_global_lock); |
- | |
| 210 | printf(":"); |
- | |
| 211 | } |
219 | } |
| 212 | } |
220 | } |
| 213 | 221 | ||
| 214 | 222 | ||