Ignore:
File:
1 edited

Legend:

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

    r14ecd6c r4acaa7c0  
    4747void ipc_kbox_cleanup(void)
    4848{
    49         ipl_t ipl;
    50         bool have_kb_thread;
    51 
    52         /*
     49        /*
    5350         * Only hold kb.cleanup_lock while setting kb.finished -
    5451         * this is enough.
     
    5754        TASK->kb.finished = true;
    5855        mutex_unlock(&TASK->kb.cleanup_lock);
    59 
    60         have_kb_thread = (TASK->kb.thread != NULL);
    61 
     56       
     57        bool have_kb_thread = (TASK->kb.thread != NULL);
     58       
    6259        /*
    6360         * From now on nobody will try to connect phones or attach
    6461         * kbox threads
    6562         */
    66 
     63       
    6764        /*
    6865         * Disconnect all phones connected to our kbox. Passing true for
     
    7269         */
    7370        ipc_answerbox_slam_phones(&TASK->kb.box, have_kb_thread);
    74 
    75         /* 
     71       
     72        /*
    7673         * If the task was being debugged, clean up debugging session.
    7774         * This is necessarry as slamming the phones won't force
    7875         * kbox thread to clean it up since sender != debugger.
    7976         */
    80         ipl = interrupts_disable();
    81         spinlock_lock(&TASK->lock);
     77        mutex_lock(&TASK->udebug.lock);
    8278        udebug_task_cleanup(TASK);
    83         spinlock_unlock(&TASK->lock);
    84         interrupts_restore(ipl);
     79        mutex_unlock(&TASK->udebug.lock);
    8580       
    8681        if (have_kb_thread) {
     
    9186                TASK->kb.thread = NULL;
    9287        }
    93 
     88       
    9489        /* Answer all messages in 'calls' and 'dispatched_calls' queues. */
    95         spinlock_lock(&TASK->kb.box.lock);
     90        irq_spinlock_lock(&TASK->kb.box.lock, true);
    9691        ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
    9792        ipc_cleanup_call_list(&TASK->kb.box.calls);
    98         spinlock_unlock(&TASK->kb.box.lock);
     93        irq_spinlock_unlock(&TASK->kb.box.lock, true);
    9994}
    10095
    10196/** Handle hangup message in kbox.
    10297 *
    103  * @param call  The IPC_M_PHONE_HUNGUP call structure.
    104  * @param last  Output, the function stores @c true here if
    105  *              this was the last phone, @c false otherwise.
    106  **/
     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 */
    107103static void kbox_proc_phone_hungup(call_t *call, bool *last)
    108104{
    109         ipl_t ipl;
    110 
    111105        /* Was it our debugger, who hung up? */
    112106        if (call->sender == TASK->udebug.debugger) {
    113107                /* Terminate debugging session (if any). */
    114108                LOG("Terminate debugging session.");
    115                 ipl = interrupts_disable();
    116                 spinlock_lock(&TASK->lock);
     109                irq_spinlock_lock(&TASK->lock, true);
    117110                udebug_task_cleanup(TASK);
    118                 spinlock_unlock(&TASK->lock);
    119                 interrupts_restore(ipl);
     111                irq_spinlock_unlock(&TASK->lock, true);
    120112        } else {
    121113                LOG("Was not debugger.");
    122114        }
    123 
     115       
    124116        LOG("Continue with hangup message.");
    125117        IPC_SET_RETVAL(call->data, 0);
    126118        ipc_answer(&TASK->kb.box, call);
    127 
    128         ipl = interrupts_disable();
    129         spinlock_lock(&TASK->lock);
    130         spinlock_lock(&TASK->kb.box.lock);
     119       
     120        mutex_lock(&TASK->kb.cleanup_lock);
     121       
     122        irq_spinlock_lock(&TASK->lock, true);
     123        irq_spinlock_lock(&TASK->kb.box.lock, false);
    131124        if (list_empty(&TASK->kb.box.connected_phones)) {
    132125                /*
     
    134127                 * gets freed and signal to the caller.
    135128                 */
    136 
     129               
    137130                /* Only detach kbox thread unless already terminating. */
    138                 mutex_lock(&TASK->kb.cleanup_lock);
    139131                if (TASK->kb.finished == false) {
    140132                        /* Detach kbox thread so it gets freed from memory. */
     
    142134                        TASK->kb.thread = NULL;
    143135                }
    144                 mutex_unlock(&TASK->kb.cleanup_lock);
    145 
     136               
    146137                LOG("Phone list is empty.");
    147138                *last = true;
    148         } else {
     139        } else
    149140                *last = false;
    150         }
    151 
    152         spinlock_unlock(&TASK->kb.box.lock);
    153         spinlock_unlock(&TASK->lock);
    154         interrupts_restore(ipl);
     141       
     142        irq_spinlock_unlock(&TASK->kb.box.lock, false);
     143        irq_spinlock_unlock(&TASK->lock, true);
     144       
     145        mutex_unlock(&TASK->kb.cleanup_lock);
    155146}
    156147
     
    160151 * when all phones are disconnected from the kbox.
    161152 *
    162  * @param arg   Ignored.
     153 * @param arg Ignored.
     154 *
    163155 */
    164156static void kbox_thread_proc(void *arg)
    165157{
    166         call_t *call;
    167         bool done;
    168 
    169         (void)arg;
     158        (void) arg;
    170159        LOG("Starting.");
    171         done = false;
    172 
     160        bool done = false;
     161       
    173162        while (!done) {
    174                 call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
     163                call_t *call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
    175164                        SYNCH_FLAGS_NONE);
    176 
     165               
    177166                if (call == NULL)
    178                         continue;       /* Try again. */
    179 
     167                        continue;  /* Try again. */
     168               
    180169                switch (IPC_GET_METHOD(call->data)) {
    181 
     170               
    182171                case IPC_M_DEBUG_ALL:
    183172                        /* Handle debug call. */
    184173                        udebug_call_receive(call);
    185174                        break;
    186 
     175               
    187176                case IPC_M_PHONE_HUNGUP:
    188177                        /*
     
    193182                        kbox_proc_phone_hungup(call, &done);
    194183                        break;
    195 
     184               
    196185                default:
    197186                        /* Ignore */
     
    199188                }
    200189        }
    201 
     190       
    202191        LOG("Exiting.");
    203192}
    204193
    205194
    206 /**
    207  * Connect phone to a task kernel-box specified by id.
     195/** Connect phone to a task kernel-box specified by id.
    208196 *
    209197 * Note that this is not completely atomic. For optimisation reasons, the task
     
    212200 * cleanup code.
    213201 *
    214  * @return              Phone id on success, or negative error code.
     202 * @return Phone id on success, or negative error code.
     203 *
    215204 */
    216205int ipc_connect_kbox(task_id_t taskid)
    217206{
    218         int newphid;
    219         task_t *ta;
    220         thread_t *kb_thread;
    221         ipl_t ipl;
    222 
    223         ipl = interrupts_disable();
    224         spinlock_lock(&tasks_lock);
    225 
    226         ta = task_find_by_id(taskid);
    227         if (ta == NULL) {
    228                 spinlock_unlock(&tasks_lock);
    229                 interrupts_restore(ipl);
     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);
    230212                return ENOENT;
    231213        }
    232 
    233         atomic_inc(&ta->refcount);
    234 
    235         spinlock_unlock(&tasks_lock);
    236         interrupts_restore(ipl);
    237 
    238         mutex_lock(&ta->kb.cleanup_lock);
    239 
    240         if (atomic_predec(&ta->refcount) == 0) {
    241                 mutex_unlock(&ta->kb.cleanup_lock);
    242                 task_destroy(ta);
     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);
    243224                return ENOENT;
    244225        }
    245 
    246         if (ta->kb.finished != false) {
    247                 mutex_unlock(&ta->kb.cleanup_lock);
     226       
     227        if (task->kb.finished != false) {
     228                mutex_unlock(&task->kb.cleanup_lock);
    248229                return EINVAL;
    249230        }
    250 
    251         newphid = phone_alloc(TASK);
     231       
     232        int newphid = phone_alloc(TASK);
    252233        if (newphid < 0) {
    253                 mutex_unlock(&ta->kb.cleanup_lock);
     234                mutex_unlock(&task->kb.cleanup_lock);
    254235                return ELIMIT;
    255236        }
    256 
     237       
    257238        /* Connect the newly allocated phone to the kbox */
    258         ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box);
    259 
    260         if (ta->kb.thread != NULL) {
    261                 mutex_unlock(&ta->kb.cleanup_lock);
     239        ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
     240       
     241        if (task->kb.thread != NULL) {
     242                mutex_unlock(&task->kb.cleanup_lock);
    262243                return newphid;
    263244        }
    264 
     245       
    265246        /* Create a kbox thread */
    266         kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0,
     247        thread_t *kb_thread = thread_create(kbox_thread_proc, NULL, task, 0,
    267248            "kbox", false);
    268249        if (!kb_thread) {
    269                 mutex_unlock(&ta->kb.cleanup_lock);
     250                mutex_unlock(&task->kb.cleanup_lock);
    270251                return ENOMEM;
    271252        }
    272 
    273         ta->kb.thread = kb_thread;
     253       
     254        task->kb.thread = kb_thread;
    274255        thread_ready(kb_thread);
    275 
    276         mutex_unlock(&ta->kb.cleanup_lock);
    277 
     256       
     257        mutex_unlock(&task->kb.cleanup_lock);
     258       
    278259        return newphid;
    279260}
Note: See TracChangeset for help on using the changeset viewer.