Changes in kernel/generic/src/ipc/kbox.c [4acaa7c0:f173404] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/kbox.c
r4acaa7c0 rf173404 47 47 void ipc_kbox_cleanup(void) 48 48 { 49 /* 49 bool have_kb_thread; 50 51 /* 50 52 * Only hold kb.cleanup_lock while setting kb.finished - 51 53 * this is enough. … … 54 56 TASK->kb.finished = true; 55 57 mutex_unlock(&TASK->kb.cleanup_lock); 56 57 boolhave_kb_thread = (TASK->kb.thread != NULL);58 58 59 have_kb_thread = (TASK->kb.thread != NULL); 60 59 61 /* 60 62 * From now on nobody will try to connect phones or attach 61 63 * kbox threads 62 64 */ 63 65 64 66 /* 65 67 * Disconnect all phones connected to our kbox. Passing true for … … 69 71 */ 70 72 ipc_answerbox_slam_phones(&TASK->kb.box, have_kb_thread); 71 72 /* 73 74 /* 73 75 * If the task was being debugged, clean up debugging session. 74 76 * This is necessarry as slamming the phones won't force … … 78 80 udebug_task_cleanup(TASK); 79 81 mutex_unlock(&TASK->udebug.lock); 80 82 81 83 if (have_kb_thread) { 82 84 LOG("Join kb.thread."); … … 86 88 TASK->kb.thread = NULL; 87 89 } 88 90 89 91 /* Answer all messages in 'calls' and 'dispatched_calls' queues. */ 90 irq_spinlock_lock(&TASK->kb.box.lock, true);92 spinlock_lock(&TASK->kb.box.lock); 91 93 ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls); 92 94 ipc_cleanup_call_list(&TASK->kb.box.calls); 93 irq_spinlock_unlock(&TASK->kb.box.lock, true);95 spinlock_unlock(&TASK->kb.box.lock); 94 96 } 95 97 96 98 /** Handle hangup message in kbox. 97 99 * 98 * @param call The IPC_M_PHONE_HUNGUP call structure. 99 * @param last Output, the function stores @c true here if 100 * this was the last phone, @c false otherwise. 101 * 102 */ 100 * @param call The IPC_M_PHONE_HUNGUP call structure. 101 * @param last Output, the function stores @c true here if 102 * this was the last phone, @c false otherwise. 103 **/ 103 104 static void kbox_proc_phone_hungup(call_t *call, bool *last) 104 105 { 106 ipl_t ipl; 107 105 108 /* Was it our debugger, who hung up? */ 106 109 if (call->sender == TASK->udebug.debugger) { 107 110 /* Terminate debugging session (if any). */ 108 111 LOG("Terminate debugging session."); 109 irq_spinlock_lock(&TASK->lock, true); 112 ipl = interrupts_disable(); 113 spinlock_lock(&TASK->lock); 110 114 udebug_task_cleanup(TASK); 111 irq_spinlock_unlock(&TASK->lock, true); 115 spinlock_unlock(&TASK->lock); 116 interrupts_restore(ipl); 112 117 } else { 113 118 LOG("Was not debugger."); 114 119 } 115 120 116 121 LOG("Continue with hangup message."); 117 122 IPC_SET_RETVAL(call->data, 0); 118 123 ipc_answer(&TASK->kb.box, call); 119 124 120 125 mutex_lock(&TASK->kb.cleanup_lock); 121 122 irq_spinlock_lock(&TASK->lock, true); 123 irq_spinlock_lock(&TASK->kb.box.lock, false); 126 127 ipl = interrupts_disable(); 128 spinlock_lock(&TASK->lock); 129 spinlock_lock(&TASK->kb.box.lock); 124 130 if (list_empty(&TASK->kb.box.connected_phones)) { 125 131 /* … … 127 133 * gets freed and signal to the caller. 128 134 */ 129 135 130 136 /* Only detach kbox thread unless already terminating. */ 131 137 if (TASK->kb.finished == false) { … … 134 140 TASK->kb.thread = NULL; 135 141 } 136 142 137 143 LOG("Phone list is empty."); 138 144 *last = true; 139 } else 145 } else { 140 146 *last = false; 141 142 irq_spinlock_unlock(&TASK->kb.box.lock, false); 143 irq_spinlock_unlock(&TASK->lock, true); 144 147 } 148 149 spinlock_unlock(&TASK->kb.box.lock); 150 spinlock_unlock(&TASK->lock); 151 interrupts_restore(ipl); 152 145 153 mutex_unlock(&TASK->kb.cleanup_lock); 146 154 } … … 151 159 * when all phones are disconnected from the kbox. 152 160 * 153 * @param arg Ignored. 154 * 161 * @param arg Ignored. 155 162 */ 156 163 static void kbox_thread_proc(void *arg) 157 164 { 158 (void) arg; 165 call_t *call; 166 bool done; 167 168 (void)arg; 159 169 LOG("Starting."); 160 booldone = false;161 170 done = false; 171 162 172 while (!done) { 163 call _t *call= ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,173 call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT, 164 174 SYNCH_FLAGS_NONE); 165 175 166 176 if (call == NULL) 167 continue; 168 177 continue; /* Try again. */ 178 169 179 switch (IPC_GET_METHOD(call->data)) { 170 180 171 181 case IPC_M_DEBUG_ALL: 172 182 /* Handle debug call. */ 173 183 udebug_call_receive(call); 174 184 break; 175 185 176 186 case IPC_M_PHONE_HUNGUP: 177 187 /* … … 182 192 kbox_proc_phone_hungup(call, &done); 183 193 break; 184 194 185 195 default: 186 196 /* Ignore */ … … 188 198 } 189 199 } 190 200 191 201 LOG("Exiting."); 192 202 } 193 203 194 204 195 /** Connect phone to a task kernel-box specified by id. 205 /** 206 * Connect phone to a task kernel-box specified by id. 196 207 * 197 208 * Note that this is not completely atomic. For optimisation reasons, the task … … 200 211 * cleanup code. 201 212 * 202 * @return Phone id on success, or negative error code. 203 * 213 * @return Phone id on success, or negative error code. 204 214 */ 205 215 int ipc_connect_kbox(task_id_t taskid) 206 216 { 207 irq_spinlock_lock(&tasks_lock, true); 208 209 task_t *task = task_find_by_id(taskid); 210 if (task == NULL) { 211 irq_spinlock_unlock(&tasks_lock, true); 217 int newphid; 218 task_t *ta; 219 thread_t *kb_thread; 220 ipl_t ipl; 221 222 ipl = interrupts_disable(); 223 spinlock_lock(&tasks_lock); 224 225 ta = task_find_by_id(taskid); 226 if (ta == NULL) { 227 spinlock_unlock(&tasks_lock); 228 interrupts_restore(ipl); 212 229 return ENOENT; 213 230 } 214 215 atomic_inc(&task->refcount); 216 217 irq_spinlock_unlock(&tasks_lock, true); 218 219 mutex_lock(&task->kb.cleanup_lock); 220 221 if (atomic_predec(&task->refcount) == 0) { 222 mutex_unlock(&task->kb.cleanup_lock); 223 task_destroy(task); 231 232 atomic_inc(&ta->refcount); 233 234 spinlock_unlock(&tasks_lock); 235 interrupts_restore(ipl); 236 237 mutex_lock(&ta->kb.cleanup_lock); 238 239 if (atomic_predec(&ta->refcount) == 0) { 240 mutex_unlock(&ta->kb.cleanup_lock); 241 task_destroy(ta); 224 242 return ENOENT; 225 243 } 226 227 if (ta sk->kb.finished != false) {228 mutex_unlock(&ta sk->kb.cleanup_lock);244 245 if (ta->kb.finished != false) { 246 mutex_unlock(&ta->kb.cleanup_lock); 229 247 return EINVAL; 230 248 } 231 232 intnewphid = phone_alloc(TASK);249 250 newphid = phone_alloc(TASK); 233 251 if (newphid < 0) { 234 mutex_unlock(&ta sk->kb.cleanup_lock);252 mutex_unlock(&ta->kb.cleanup_lock); 235 253 return ELIMIT; 236 254 } 237 255 238 256 /* Connect the newly allocated phone to the kbox */ 239 ipc_phone_connect(&TASK->phones[newphid], &ta sk->kb.box);240 241 if (ta sk->kb.thread != NULL) {242 mutex_unlock(&ta sk->kb.cleanup_lock);257 ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box); 258 259 if (ta->kb.thread != NULL) { 260 mutex_unlock(&ta->kb.cleanup_lock); 243 261 return newphid; 244 262 } 245 263 246 264 /* Create a kbox thread */ 247 thread_t *kb_thread = thread_create(kbox_thread_proc, NULL, task, 0,265 kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0, 248 266 "kbox", false); 249 267 if (!kb_thread) { 250 mutex_unlock(&ta sk->kb.cleanup_lock);268 mutex_unlock(&ta->kb.cleanup_lock); 251 269 return ENOMEM; 252 270 } 253 254 ta sk->kb.thread = kb_thread;271 272 ta->kb.thread = kb_thread; 255 273 thread_ready(kb_thread); 256 257 mutex_unlock(&ta sk->kb.cleanup_lock);258 274 275 mutex_unlock(&ta->kb.cleanup_lock); 276 259 277 return newphid; 260 278 }
Note:
See TracChangeset
for help on using the changeset viewer.