Ignore:
File:
1 edited

Legend:

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

    rda1bafb r2c0e5d2  
    4545 * - hangup phone (the caller has hung up)
    4646 * - hangup phone (the answerbox is exiting)
    47  *
     47 * 
    4848 * Locking strategy
    4949 *
     
    8585 *
    8686 * Phone hangup
    87  *
     87 * 
    8888 * *** The caller hangs up (sys_ipc_hangup) ***
    8989 * - The phone is disconnected (no more messages can be sent over this phone),
     
    9999 *
    100100 * Call forwarding
    101  *
     101 * 
    102102 * The call can be forwarded, so that the answer to call is passed directly
    103103 * to the original sender. However, this poses special problems regarding
     
    114114 *
    115115 * Cleanup strategy
    116  *
     116 * 
    117117 * 1) Disconnect all our phones ('ipc_phone_hangup').
    118118 *
     
    123123 *
    124124 * 4) Wait for all async answers to arrive and dispose of them.
    125  *
     125 * 
    126126 */
    127127
     
    137137 * @todo Some speedup (hash table?)
    138138 *
    139  * @param callid Userspace hash of the call. Currently it is the call
    140  *               structure kernel address.
    141  *
    142  * @return NULL on not found, otherwise pointer to the call
    143  *         structure.
    144  *
     139 * @param callid        Userspace hash of the call. Currently it is the call
     140 *                      structure kernel address.
     141 *
     142 * @return              NULL on not found, otherwise pointer to the call
     143 *                      structure.
    145144 */
    146145call_t *get_call(unative_t callid)
    147146{
    148147        link_t *lst;
    149         call_t *result = NULL;
    150        
    151         irq_spinlock_lock(&TASK->answerbox.lock, true);
     148        call_t *call, *result = NULL;
     149
     150        spinlock_lock(&TASK->answerbox.lock);
    152151        for (lst = TASK->answerbox.dispatched_calls.next;
    153152            lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
    154                 call_t *call = list_get_instance(lst, call_t, link);
     153                call = list_get_instance(lst, call_t, link);
    155154                if ((unative_t) call == callid) {
    156155                        result = call;
     
    158157                }
    159158        }
    160        
    161         irq_spinlock_unlock(&TASK->answerbox.lock, true);
     159        spinlock_unlock(&TASK->answerbox.lock);
    162160        return result;
    163161}
     
    165163/** Allocate new phone slot in the specified task.
    166164 *
    167  * @param task Task for which to allocate a new phone.
    168  *
    169  * @return New phone handle or -1 if the phone handle limit is
    170  *         exceeded.
    171  *
    172  */
    173 int phone_alloc(task_t *task)
    174 {
    175         irq_spinlock_lock(&task->lock, true);
    176        
    177         size_t i;
     165 * @param t             Task for which to allocate a new phone.
     166 *
     167 * @return              New phone handle or -1 if the phone handle limit is
     168 *                      exceeded.
     169 */
     170int phone_alloc(task_t *t)
     171{
     172        int i;
     173
     174        spinlock_lock(&t->lock);
    178175        for (i = 0; i < IPC_MAX_PHONES; i++) {
    179                 if ((task->phones[i].state == IPC_PHONE_HUNGUP) &&
    180                     (atomic_get(&task->phones[i].active_calls) == 0))
    181                         task->phones[i].state = IPC_PHONE_FREE;
    182                
    183                 if (task->phones[i].state == IPC_PHONE_FREE) {
    184                         task->phones[i].state = IPC_PHONE_CONNECTING;
     176                if (t->phones[i].state == IPC_PHONE_HUNGUP &&
     177                    atomic_get(&t->phones[i].active_calls) == 0)
     178                        t->phones[i].state = IPC_PHONE_FREE;
     179
     180                if (t->phones[i].state == IPC_PHONE_FREE) {
     181                        t->phones[i].state = IPC_PHONE_CONNECTING;
    185182                        break;
    186183                }
    187184        }
    188        
    189         irq_spinlock_unlock(&task->lock, true);
    190        
     185        spinlock_unlock(&t->lock);
     186
    191187        if (i == IPC_MAX_PHONES)
    192188                return -1;
    193        
     189
    194190        return i;
    195191}
     
    197193/** Mark a phone structure free.
    198194 *
    199  * @param phone Phone structure to be marked free.
    200  *
     195 * @param phone         Phone structure to be marked free.
    201196 */
    202197static void phone_deallocp(phone_t *phone)
     
    204199        ASSERT(phone->state == IPC_PHONE_CONNECTING);
    205200       
    206         /* Atomic operation */
     201        /* atomic operation */
    207202        phone->state = IPC_PHONE_FREE;
    208203}
     
    212207 * All already sent messages will be correctly processed.
    213208 *
    214  * @param phoneid Phone handle of the phone to be freed.
    215  *
     209 * @param phoneid       Phone handle of the phone to be freed.
    216210 */
    217211void phone_dealloc(int phoneid)
     
    222216/** Connect phone to a given answerbox.
    223217 *
    224  * @param phoneid Phone handle to be connected.
    225  * @param box     Answerbox to which to connect the phone handle.
     218 * @param phoneid       Phone handle to be connected.
     219 * @param box           Answerbox to which to connect the phone handle.
    226220 *
    227221 * The procedure _enforces_ that the user first marks the phone
    228222 * busy (e.g. via phone_alloc) and then connects the phone, otherwise
    229223 * race condition may appear.
    230  *
    231224 */
    232225void phone_connect(int phoneid, answerbox_t *box)
Note: See TracChangeset for help on using the changeset viewer.