Changeset 05ffb41 in mainline for kernel/generic/src/ipc/ipcrsc.c


Ignore:
Timestamp:
2017-08-17T19:11:14Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1c85bae
Parents:
7e3826d9
Message:

Turn IPC phones into kobjects

File:
1 edited

Legend:

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

    r7e3826d9 r05ffb41  
    162162}
    163163
    164 /** Get phone from the current task by ID.
    165  *
    166  * @param phoneid Phone ID.
    167  * @param phone   Place to store pointer to phone.
    168  *
    169  * @return EOK on success, EINVAL if ID is invalid.
    170  *
    171  */
    172 int phone_get(sysarg_t phoneid, phone_t **phone)
    173 {
    174         if (phoneid >= IPC_MAX_PHONES)
    175                 return EINVAL;
    176        
    177         *phone = &TASK->phones[phoneid];
    178         return EOK;
    179 }
    180 
    181 /** Allocate new phone slot in the specified task.
    182  *
    183  * @param task Task for which to allocate a new phone.
    184  *
    185  * @return New phone handle or -1 if the phone handle limit is
    186  *         exceeded.
    187  *
     164/** Get phone from the current task by capability.
     165 *
     166 * @param cap    Phone capability.
     167 * @param phone  Place to store pointer to phone.
     168 *
     169 * @return  Address of the phone kernel object.
     170 * @return  NULL if the capability is invalid.
     171 *
     172 */
     173phone_t *phone_get(task_t *task, int cap)
     174{
     175        kobject_t *kobj = kobject_get(task, cap, KOBJECT_TYPE_PHONE);
     176        if (!kobj)
     177                return NULL;
     178       
     179        return &kobj->phone;
     180}
     181
     182phone_t *phone_get_current(int cap)
     183{
     184        return phone_get(TASK, cap);
     185}
     186
     187static bool phone_can_reclaim(kobject_t *kobj)
     188{
     189        assert(kobj->type == KOBJECT_TYPE_PHONE);
     190
     191        return (kobj->phone.state == IPC_PHONE_HUNGUP) &&
     192            (atomic_get(&kobj->phone.active_calls) == 0);
     193}
     194
     195/** Allocate new phone in the specified task.
     196 *
     197 * @param task  Task for which to allocate a new phone.
     198 *
     199 * @return  New phone capability.
     200 * @return  KOBJECT_INVALID_CAP if a new capability cannot be allocated.
    188201 */
    189202int phone_alloc(task_t *task)
    190203{
    191         irq_spinlock_lock(&task->lock, true);
    192        
    193         size_t i;
    194         for (i = 0; i < IPC_MAX_PHONES; i++) {
    195                 phone_t *phone = &task->phones[i];
    196 
    197                 if ((phone->state == IPC_PHONE_HUNGUP) &&
    198                     (atomic_get(&phone->active_calls) == 0))
    199                         phone->state = IPC_PHONE_FREE;
    200                
    201                 if (phone->state == IPC_PHONE_FREE) {
    202                         phone->state = IPC_PHONE_CONNECTING;
    203                         break;
    204                 }
     204        int cap = kobject_alloc(task);
     205        if (cap != KOBJECT_INVALID_CAP) {
     206                irq_spinlock_lock(&task->lock, true);
     207                kobject_t *kobj = &task->kobject[cap];
     208                ipc_phone_init(&kobj->phone, task);
     209                kobj->type = KOBJECT_TYPE_PHONE;
     210                kobj->can_reclaim = phone_can_reclaim;
     211                kobj->phone.state = IPC_PHONE_CONNECTING;
     212                irq_spinlock_unlock(&task->lock, true);
    205213        }
    206214       
    207         irq_spinlock_unlock(&task->lock, true);
    208        
    209         if (i == IPC_MAX_PHONES)
    210                 return -1;
    211        
    212         return i;
    213 }
    214 
    215 /** Mark a phone structure free.
    216  *
    217  * @param phone Phone structure to be marked free.
    218  *
    219  */
    220 static void phone_deallocp(phone_t *phone)
    221 {
     215        return cap;
     216}
     217
     218/** Free slot from a disconnected phone.
     219 *
     220 * All already sent messages will be correctly processed.
     221 *
     222 * @param phoneid Phone handle of the phone to be freed.
     223 *
     224 */
     225void phone_dealloc(int cap)
     226{
     227        phone_t *phone = phone_get_current(cap);
     228       
     229        assert(phone);
    222230        assert(phone->state == IPC_PHONE_CONNECTING);
    223        
    224         /* Atomic operation */
    225         phone->state = IPC_PHONE_FREE;
    226 }
    227 
    228 /** Free slot from a disconnected phone.
    229  *
    230  * All already sent messages will be correctly processed.
    231  *
    232  * @param phoneid Phone handle of the phone to be freed.
    233  *
    234  */
    235 void phone_dealloc(int phoneid)
    236 {
    237         phone_deallocp(&TASK->phones[phoneid]);
     231
     232        kobject_free(TASK, cap);
    238233}
    239234
    240235/** Connect phone to a given answerbox.
    241236 *
    242  * @param phoneid Phone handle to be connected.
    243  * @param box     Answerbox to which to connect the phone handle.
    244  * @return        True if the phone was connected, false otherwise.
    245  *
    246  * The procedure _enforces_ that the user first marks the phone
    247  * busy (e.g. via phone_alloc) and then connects the phone, otherwise
    248  * race condition may appear.
    249  *
    250  */
    251 bool phone_connect(int phoneid, answerbox_t *box)
    252 {
    253         phone_t *phone = &TASK->phones[phoneid];
    254        
     237 * @param cap  Phone capability to be connected.
     238 * @param box  Answerbox to which to connect the phone capability.
     239 * @return     True if the phone was connected, false otherwise.
     240 *
     241 * The procedure _enforces_ that the user first marks the phone busy (e.g. via
     242 * phone_alloc) and then connects the phone, otherwise race condition may
     243 * appear.
     244 *
     245 */
     246bool phone_connect(int cap, answerbox_t *box)
     247{
     248        phone_t *phone = phone_get_current(cap);
     249       
     250        assert(phone);
    255251        assert(phone->state == IPC_PHONE_CONNECTING);
     252       
    256253        return ipc_phone_connect(phone, box);
    257254}
Note: See TracChangeset for help on using the changeset viewer.