Changeset 05e69c5 in mainline


Ignore:
Timestamp:
2008-10-22T20:20:57Z (16 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c947dda
Parents:
5045a68
Message:

Split and streamline kbox_thread_proc().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/kbox.c

    r5045a68 r05e69c5  
    9292}
    9393
    94 
     94/** Handle hangup message in kbox.
     95 *
     96 * @param call  The IPC_M_PHONE_HUNGUP call structure.
     97 * @param last  Output, the function stores @c true here if
     98 *              this was the last phone, @c false otherwise.
     99 **/
     100static void kbox_proc_phone_hungup(call_t *call, bool *last)
     101{
     102        ipl_t ipl;
     103
     104        LOG("kbox_proc_phone_hungup()\n");
     105
     106        /* Was it our debugger, who hung up? */
     107        if (call->sender == TASK->udebug.debugger) {
     108                /* Terminate debugging session (if any) */
     109                LOG("kbox: terminate debug session\n");
     110                ipl = interrupts_disable();
     111                spinlock_lock(&TASK->lock);
     112                udebug_task_cleanup(TASK);
     113                spinlock_unlock(&TASK->lock);
     114                interrupts_restore(ipl);
     115        } else {
     116                LOG("kbox: was not debugger\n");
     117        }
     118
     119        LOG("kbox: continue with hangup message\n");
     120        IPC_SET_RETVAL(call->data, 0);
     121        ipc_answer(&TASK->kernel_box, call);
     122
     123        ipl = interrupts_disable();
     124        spinlock_lock(&TASK->lock);
     125        spinlock_lock(&TASK->answerbox.lock);
     126        if (list_empty(&TASK->answerbox.connected_phones)) {
     127                /*
     128                 * Last phone has been disconnected. Detach this thread so it
     129                 * gets freed and signal to the caller.
     130                 */
     131
     132                /* Only detach kbox thread unless already terminating. */
     133                mutex_lock(&TASK->kb_cleanup_lock);
     134                if (&TASK->kb_finished == false) {
     135                        /* Detach kbox thread so it gets freed from memory. */
     136                        thread_detach(TASK->kb_thread);
     137                        TASK->kb_thread = NULL;
     138                }
     139                mutex_unlock(&TASK->kb_cleanup_lock);
     140
     141                LOG("phone list is empty\n");
     142                *last = true;
     143        } else {
     144                *last = false;
     145        }
     146
     147        spinlock_unlock(&TASK->answerbox.lock);
     148        spinlock_unlock(&TASK->lock);
     149        interrupts_restore(ipl);
     150}
     151
     152/** Implementing function for the kbox thread.
     153 *
     154 * This function listens for debug requests. It terminates
     155 * when all phones are disconnected from the kbox.
     156 *
     157 * @param arg   Ignored.
     158 */
    95159static void kbox_thread_proc(void *arg)
    96160{
    97161        call_t *call;
    98         int method;
    99162        bool done;
    100         ipl_t ipl;
    101163
    102164        (void)arg;
     
    108170                        SYNCH_FLAGS_NONE);
    109171
    110                 if (call != NULL) {
    111                         method = IPC_GET_METHOD(call->data);
    112 
    113                         if (method == IPC_M_DEBUG_ALL) {
    114                                 udebug_call_receive(call);
    115                         }
    116 
    117                         if (method == IPC_M_PHONE_HUNGUP) {
    118                                 LOG("kbox: handle hangup message\n");
    119 
    120                                 /* Was it our debugger, who hung up? */
    121                                 if (call->sender == TASK->udebug.debugger) {
    122                                         /* Terminate debugging session (if any) */
    123                                         LOG("kbox: terminate debug session\n");
    124                                         ipl = interrupts_disable();
    125                                         spinlock_lock(&TASK->lock);
    126                                         udebug_task_cleanup(TASK);
    127                                         spinlock_unlock(&TASK->lock);
    128                                         interrupts_restore(ipl);
    129                                 } else {
    130                                         LOG("kbox: was not debugger\n");
    131                                 }
    132 
    133                                 LOG("kbox: continue with hangup message\n");
    134                                 IPC_SET_RETVAL(call->data, 0);
    135                                 ipc_answer(&TASK->kernel_box, call);
    136 
    137                                 ipl = interrupts_disable();
    138                                 spinlock_lock(&TASK->lock);
    139                                 spinlock_lock(&TASK->answerbox.lock);
    140                                 if (list_empty(&TASK->answerbox.connected_phones)) {
    141                                         /*
    142                                          * Last phone has been disconnected.
    143                                          * Detach this thread so it gets
    144                                          * freed and terminate.
    145                                          */
    146 
    147                                         /* Only need to detach thread unless already terminating. */
    148                                         mutex_lock(&TASK->kb_cleanup_lock);
    149                                         if (&TASK->kb_finished == false) {
    150                                                 /* Detach thread so it gets freed. */
    151                                                 thread_detach(TASK->kb_thread);
    152                                                 TASK->kb_thread = NULL;
    153                                         }
    154                                         mutex_unlock(&TASK->kb_cleanup_lock);
    155                                         done = true;
    156                                         LOG("phone list is empty\n");
    157                                 }
    158                                 spinlock_unlock(&TASK->answerbox.lock);
    159                                 spinlock_unlock(&TASK->lock);
    160                                 interrupts_restore(ipl);
    161                         }
     172                if (call == NULL)
     173                        continue;       /* Try again. */
     174
     175                switch (IPC_GET_METHOD(call->data)) {
     176
     177                case IPC_M_DEBUG_ALL:
     178                        /* Handle debug call. */
     179                        udebug_call_receive(call);
     180                        break;
     181
     182                case IPC_M_PHONE_HUNGUP:
     183                        /*
     184                         * Process the hangup call. If this was the last
     185                         * phone, done will be set to true and the
     186                         * while loop will terminate.
     187                         */
     188                        kbox_proc_phone_hungup(call, &done);
     189                        break;
     190
     191                default:
     192                        /* Ignore */
     193                        break;
    162194                }
    163195        }
Note: See TracChangeset for help on using the changeset viewer.