Changeset 05ffb41 in mainline


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

Location:
kernel/generic
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    r7e3826d9 r05ffb41  
    4343#include <typedefs.h>
    4444
    45 #define IPC_MAX_PHONES  64
    46 
    4745struct answerbox;
    4846struct task;
  • kernel/generic/include/ipc/ipcrsc.h

    r7e3826d9 r05ffb41  
    4040
    4141extern call_t *get_call(sysarg_t);
    42 extern int phone_get(sysarg_t, phone_t **);
     42extern phone_t *phone_get_current(int);
     43extern phone_t *phone_get(task_t *, int);
    4344extern int phone_alloc(task_t *);
    4445extern bool phone_connect(int, answerbox_t *);
  • kernel/generic/include/kobject/kobject.h

    r7e3826d9 r05ffb41  
    3737
    3838#include <typedefs.h>
     39#include <ipc/ipc.h>
    3940
    4041#define MAX_KERNEL_OBJECTS  64
     
    4445typedef enum {
    4546        KOBJECT_TYPE_INVALID,
    46         KOBJECT_TYPE_ALLOCATED
     47        KOBJECT_TYPE_ALLOCATED,
     48        KOBJECT_TYPE_PHONE
    4749} kobject_type_t;
    4850
    49 typedef struct {
     51typedef struct kobject {
    5052        kobject_type_t type;
     53        bool (* can_reclaim)(struct kobject *);
     54
    5155        union {
     56                phone_t phone;
    5257        };
    5358} kobject_t;
    5459
    55 extern kobject_t *kobject_get_local(int, kobject_type_t);
     60struct task;
    5661
    57 struct task;
     62extern void kobject_init(kobject_t *);
     63extern kobject_t *kobject_get(struct task *, int, kobject_type_t);
     64extern kobject_t *kobject_get_current(int, kobject_type_t);
    5865extern int kobject_alloc(struct task *);
    5966extern void kobject_free(struct task *, int);
  • kernel/generic/include/proc/task.h

    r7e3826d9 r05ffb41  
    105105        answerbox_t answerbox;
    106106
    107         /** Sending communication endpoints */
    108         phone_t phones[IPC_MAX_PHONES];
    109 
    110107        /** Spinlock protecting the active_calls list. */
    111108        SPINLOCK_DECLARE(active_calls_lock);
  • kernel/generic/src/ipc/ipc.c

    r7e3826d9 r05ffb41  
    4343#include <synch/waitq.h>
    4444#include <ipc/ipc.h>
     45#include <ipc/ipcrsc.h>
    4546#include <abi/ipc/methods.h>
    4647#include <ipc/kbox.h>
     
    740741         * Locking is needed as there may be connection handshakes in progress.
    741742         */
    742         for (i = 0; i < IPC_MAX_PHONES; i++) {
    743                 phone_t *phone = &TASK->phones[i];
    744 
    745                 mutex_lock(&phone->lock);       
     743        for (i = 0; i < MAX_KERNEL_OBJECTS; i++) {
     744                phone_t *phone = phone_get_current(i);
     745                if (!phone)
     746                        continue;
     747
     748                mutex_lock(&phone->lock);
    746749                if ((phone->state == IPC_PHONE_HUNGUP) &&
    747750                    (atomic_get(&phone->active_calls) == 0)) {
     
    784787               
    785788        /* Got into cleanup */
    786         if (i == IPC_MAX_PHONES)
     789        if (i == MAX_KERNEL_OBJECTS)
    787790                return;
    788791               
     
    816819
    817820        /* Disconnect all our phones ('ipc_phone_hangup') */
    818         for (size_t i = 0; i < IPC_MAX_PHONES; i++)
    819                 ipc_phone_hangup(&TASK->phones[i]);
     821        for (int i = 0; i < MAX_KERNEL_OBJECTS; i++) {
     822                phone_t *phone = phone_get_current(i);
     823                if (!phone)
     824                        continue;
     825                ipc_phone_hangup(phone);
     826        }
    820827       
    821828        /* Unsubscribe from any event notifications. */
     
    903910        irq_spinlock_exchange(&tasks_lock, &task->lock);
    904911       
    905         printf("[phone id] [calls] [state\n");
     912        printf("[phone cap] [calls] [state\n");
    906913       
    907914        size_t i;
    908         for (i = 0; i < IPC_MAX_PHONES; i++) {
    909                 if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
     915        for (i = 0; i < MAX_KERNEL_OBJECTS; i++) {
     916                phone_t *phone = phone_get(task, i);
     917                if (!phone)
     918                        continue;
     919
     920                if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
    910921                        printf("%-10zu (mutex busy)\n", i);
    911922                        continue;
    912923                }
    913924               
    914                 if (task->phones[i].state != IPC_PHONE_FREE) {
    915                         printf("%-10zu %7" PRIun " ", i,
    916                             atomic_get(&task->phones[i].active_calls));
     925                if (phone->state != IPC_PHONE_FREE) {
     926                        printf("%-11zu %7" PRIun " ", i,
     927                            atomic_get(&phone->active_calls));
    917928                       
    918                         switch (task->phones[i].state) {
     929                        switch (phone->state) {
    919930                        case IPC_PHONE_CONNECTING:
    920931                                printf("connecting");
     
    922933                        case IPC_PHONE_CONNECTED:
    923934                                printf("connected to %" PRIu64 " (%s)",
    924                                     task->phones[i].callee->task->taskid,
    925                                     task->phones[i].callee->task->name);
     935                                    phone->callee->task->taskid,
     936                                    phone->callee->task->name);
    926937                                break;
    927938                        case IPC_PHONE_SLAMMED:
    928                                 printf("slammed by %p",
    929                                     task->phones[i].callee);
     939                                printf("slammed by %p", phone->callee);
    930940                                break;
    931941                        case IPC_PHONE_HUNGUP:
    932                                 printf("hung up by %p",
    933                                     task->phones[i].callee);
     942                                printf("hung up by %p", phone->callee);
    934943                                break;
    935944                        default:
     
    940949                }
    941950               
    942                 mutex_unlock(&task->phones[i].lock);
     951                mutex_unlock(&phone->lock);
    943952        }
    944953       
  • 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}
  • kernel/generic/src/ipc/kbox.c

    r7e3826d9 r05ffb41  
    206206 * cleanup code.
    207207 *
    208  * @return Phone id on success, or negative error code.
     208 * @return Phone capability on success, or negative error code.
    209209 *
    210210 */
     
    236236        }
    237237       
    238         int newphid = phone_alloc(TASK);
    239         if (newphid < 0) {
     238        int cap = phone_alloc(TASK);
     239        if (cap < 0) {
    240240                mutex_unlock(&task->kb.cleanup_lock);
    241241                return ELIMIT;
     
    243243       
    244244        /* Connect the newly allocated phone to the kbox */
    245         (void) ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
     245        (void) ipc_phone_connect(phone_get_current(cap), &task->kb.box);
    246246       
    247247        if (task->kb.thread != NULL) {
    248248                mutex_unlock(&task->kb.cleanup_lock);
    249                 return newphid;
     249                return cap;
    250250        }
    251251       
     
    263263        mutex_unlock(&task->kb.cleanup_lock);
    264264       
    265         return newphid;
     265        return cap;
    266266}
    267267
  • kernel/generic/src/ipc/ops/conctmeto.c

    r7e3826d9 r05ffb41  
    4242static int request_preprocess(call_t *call, phone_t *phone)
    4343{
    44         int newphid = phone_alloc(TASK);
     44        int cap = phone_alloc(TASK);
    4545
    46         /* Remember the phoneid or the error. */
    47         call->priv = newphid;
    48         if (newphid < 0)
     46        /* Remember the phone capability or the error. */
     47        call->priv = cap;
     48        if (cap < 0)
    4949                return ELIMIT;
    5050               
    5151        /* Set arg5 for server */
    52         IPC_SET_ARG5(call->data, (sysarg_t) &TASK->phones[newphid]);
     52        IPC_SET_ARG5(call->data, (sysarg_t) phone_get_current(cap));
    5353
    5454        return EOK;
     
    7474static int answer_process(call_t *answer)
    7575{
    76         int newphid = (int) answer->priv;
     76        int cap = (int) answer->priv;
    7777
    7878        if (IPC_GET_RETVAL(answer->data)) {
    79                 if (newphid >= 0) {
     79                if (cap >= 0) {
    8080                        /*
    8181                         * The phone was indeed allocated and now needs
    8282                         * to be deallocated.
    8383                         */
    84                         phone_dealloc(newphid);
     84                        phone_dealloc(cap);
    8585                }
    8686        } else {
    87                 IPC_SET_ARG5(answer->data, newphid);
     87                IPC_SET_ARG5(answer->data, cap);
    8888        }
    8989       
  • kernel/generic/src/ipc/ops/concttome.c

    r7e3826d9 r05ffb41  
    4242static int request_process(call_t *call, answerbox_t *box)
    4343{
    44         int phoneid = phone_alloc(TASK);
     44        int cap = phone_alloc(TASK);
    4545
    46         IPC_SET_ARG5(call->data, phoneid);
     46        IPC_SET_ARG5(call->data, cap);
    4747       
    4848        return EOK;
     
    5151static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
    5252{
    53         int phoneid = (int) IPC_GET_ARG5(*olddata);
     53        int cap = (int) IPC_GET_ARG5(*olddata);
    5454
    55         if (phoneid >= 0)
    56                 phone_dealloc(phoneid);
     55        if (cap >= 0)
     56                phone_dealloc(cap);
    5757
    5858        return EOK;
     
    6161static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6262{
    63         int phoneid = (int) IPC_GET_ARG5(*olddata);
     63        int cap = (int) IPC_GET_ARG5(*olddata);
    6464
    6565        if (IPC_GET_RETVAL(answer->data) != EOK) {
    6666                /* The connection was not accepted */
    6767                answer_cleanup(answer, olddata);
    68         } else if (phoneid >= 0) {
     68        } else if (cap >= 0) {
    6969                /* The connection was accepted */
    70                 if (phone_connect(phoneid, &answer->sender->answerbox)) {
     70                if (phone_connect(cap, &answer->sender->answerbox)) {
    7171                        /* Set 'phone hash' as arg5 of response */
    7272                        IPC_SET_ARG5(answer->data,
    73                             (sysarg_t) &TASK->phones[phoneid]);
     73                            (sysarg_t) phone_get_current(cap));
    7474                } else {
    7575                        /* The answerbox is shutting down. */
  • kernel/generic/src/ipc/ops/connclone.c

    r7e3826d9 r05ffb41  
    6161static int request_preprocess(call_t *call, phone_t *phone)
    6262{
    63         phone_t *cloned_phone;
    64 
    65         if (phone_get(IPC_GET_ARG1(call->data), &cloned_phone) != EOK)
     63        phone_t *cloned_phone = phone_get_current(IPC_GET_ARG1(call->data));
     64        if (!cloned_phone)
    6665                return ENOENT;
    67                
     66       
    6867        phones_lock(cloned_phone, phone);
    69                
     68       
    7069        if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
    7170            phone->state != IPC_PHONE_CONNECTED) {
     
    7372                return EINVAL;
    7473        }
    75                
     74       
    7675        /*
    7776         * We can be pretty sure now that both tasks exist and we are
     
    8180         *
    8281         */
    83         int newphid = phone_alloc(phone->callee->task);
    84         if (newphid < 0) {
     82        int cap = phone_alloc(phone->callee->task);
     83        if (cap < 0) {
    8584                phones_unlock(cloned_phone, phone);
    8685                return ELIMIT;
    8786        }
    88                
    89         (void) ipc_phone_connect(&phone->callee->task->phones[newphid],
     87       
     88        (void) ipc_phone_connect(phone_get(phone->callee->task, cap),
    9089            cloned_phone->callee);
    9190        phones_unlock(cloned_phone, phone);
    92                
     91       
    9392        /* Set the new phone for the callee. */
    94         IPC_SET_ARG1(call->data, newphid);
     93        IPC_SET_ARG1(call->data, cap);
    9594
    9695        return EOK;
     
    9998static int answer_cleanup(call_t *answer, ipc_data_t *olddata)
    10099{
    101         int phoneid = (int) IPC_GET_ARG1(*olddata);
    102         phone_t *phone = &TASK->phones[phoneid];
     100        int cap = (int) IPC_GET_ARG1(*olddata);
     101        phone_t *phone = phone_get_current(cap);
    103102
    104103        /*
  • kernel/generic/src/ipc/ops/stchngath.c

    r7e3826d9 r05ffb41  
    4343static int request_preprocess(call_t *call, phone_t *phone)
    4444{
    45         phone_t *sender_phone;
    4645        task_t *other_task_s;
    4746
    48         if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
     47        phone_t *sender_phone = phone_get_current(IPC_GET_ARG5(call->data));
     48        if (!sender_phone)
    4949                return ENOENT;
    5050
     
    7575                task_t *other_task_r;
    7676
    77                 rc = phone_get(IPC_GET_ARG1(answer->data),
    78                     &recipient_phone);
    79                 if (rc != EOK) {
     77                recipient_phone = phone_get_current(IPC_GET_ARG1(answer->data));
     78                if (!recipient_phone) {
    8079                        IPC_SET_RETVAL(answer->data, ENOENT);
    8180                        return ENOENT;
  • kernel/generic/src/ipc/sysipc.c

    r7e3826d9 r05ffb41  
    264264/** Make a call over IPC and wait for reply.
    265265 *
    266  * @param phoneid     Phone handle for the call.
    267  * @param data[inout] Structure with request/reply data.
    268  * @param priv        Value to be stored in call->priv.
     266 * @param phone_cap    Phone capability for the call.
     267 * @param data[inout]  Structure with request/reply data.
     268 * @param priv         Value to be stored in call->priv.
    269269 *
    270270 * @return EOK on success.
     
    272272 *
    273273 */
    274 int ipc_req_internal(int phoneid, ipc_data_t *data, sysarg_t priv)
    275 {
    276         phone_t *phone;
    277         if (phone_get(phoneid, &phone) != EOK)
     274int ipc_req_internal(int phone_cap, ipc_data_t *data, sysarg_t priv)
     275{
     276        phone_t *phone = phone_get_current(phone_cap);
     277        if (!phone)
    278278                return ENOENT;
    279279       
     
    350350 * the generic function sys_ipc_call_async_slow().
    351351 *
    352  * @param phoneid Phone handle for the call.
    353  * @param imethod Interface and method of the call.
    354  * @param arg1    Service-defined payload argument.
    355  * @param arg2    Service-defined payload argument.
    356  * @param arg3    Service-defined payload argument.
    357  * @param arg4    Service-defined payload argument.
     352 * @param phone_cap  Phone capability for the call.
     353 * @param imethod    Interface and method of the call.
     354 * @param arg1       Service-defined payload argument.
     355 * @param arg2       Service-defined payload argument.
     356 * @param arg3       Service-defined payload argument.
     357 * @param arg4       Service-defined payload argument.
    358358 *
    359359 * @return Call hash on success.
     
    363363 *
    364364 */
    365 sysarg_t sys_ipc_call_async_fast(sysarg_t phoneid, sysarg_t imethod,
     365sysarg_t sys_ipc_call_async_fast(sysarg_t phone_cap, sysarg_t imethod,
    366366    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    367367{
    368         phone_t *phone;
    369         if (phone_get(phoneid, &phone) != EOK)
     368        phone_t *phone = phone_get_current(phone_cap);
     369        if (!phone)
    370370                return IPC_CALLRET_FATAL;
    371371       
     
    398398/** Make an asynchronous IPC call allowing to transmit the entire payload.
    399399 *
    400  * @param phoneid Phone handle for the call.
    401  * @param data    Userspace address of call data with the request.
     400 * @param phone_cap  Phone capability for the call.
     401 * @param data       Userspace address of call data with the request.
    402402 *
    403403 * @return See sys_ipc_call_async_fast().
    404404 *
    405405 */
    406 sysarg_t sys_ipc_call_async_slow(sysarg_t phoneid, ipc_data_t *data)
    407 {
    408         phone_t *phone;
    409         if (phone_get(phoneid, &phone) != EOK)
     406sysarg_t sys_ipc_call_async_slow(sysarg_t phone_cap, ipc_data_t *data)
     407{
     408        phone_t *phone = phone_get_current(phone_cap);
     409        if (!phone)
    410410                return IPC_CALLRET_FATAL;
    411411
     
    435435 * Common code for both the fast and the slow version.
    436436 *
    437  * @param callid  Hash of the call to forward.
    438  * @param phoneid Phone handle to use for forwarding.
    439  * @param imethod New interface and method to use for the forwarded call.
    440  * @param arg1    New value of the first argument for the forwarded call.
    441  * @param arg2    New value of the second argument for the forwarded call.
    442  * @param arg3    New value of the third argument for the forwarded call.
    443  * @param arg4    New value of the fourth argument for the forwarded call.
    444  * @param arg5    New value of the fifth argument for the forwarded call.
    445  * @param mode    Flags that specify mode of the forward operation.
    446  * @param slow    If true, arg3, arg4 and arg5 are considered. Otherwise
    447  *                the function considers only the fast version arguments:
    448  *                i.e. arg1 and arg2.
     437 * @param callid     Hash of the call to forward.
     438 * @param phone_cap  Phone capability to use for forwarding.
     439 * @param imethod    New interface and method to use for the forwarded call.
     440 * @param arg1       New value of the first argument for the forwarded call.
     441 * @param arg2       New value of the second argument for the forwarded call.
     442 * @param arg3       New value of the third argument for the forwarded call.
     443 * @param arg4       New value of the fourth argument for the forwarded call.
     444 * @param arg5       New value of the fifth argument for the forwarded call.
     445 * @param mode       Flags that specify mode of the forward operation.
     446 * @param slow       If true, arg3, arg4 and arg5 are considered. Otherwise
     447 *                   the function considers only the fast version arguments:
     448 *                   i.e. arg1 and arg2.
    449449 *
    450450 * @return 0 on succes, otherwise an error code.
     
    453453 *
    454454 */
    455 static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phoneid,
     455static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phone_cap,
    456456    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    457457    sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
     
    468468        bool after_forward = false;
    469469        int rc;
    470         phone_t *phone;
    471        
    472         if (phone_get(phoneid, &phone) != EOK) {
     470
     471        phone_t *phone = phone_get_current(phone_cap);
     472        if (!phone) {
    473473                rc = ENOENT;
    474474                goto error;
     
    685685/** Hang up a phone.
    686686 *
    687  * @param Phone handle of the phone to be hung up.
     687 * @param phone_cap  Phone capability of the phone to be hung up.
    688688 *
    689689 * @return 0 on success or an error code.
    690690 *
    691691 */
    692 sysarg_t sys_ipc_hangup(sysarg_t phoneid)
    693 {
    694         phone_t *phone;
    695        
    696         if (phone_get(phoneid, &phone) != EOK)
     692sysarg_t sys_ipc_hangup(sysarg_t phone_cap)
     693{
     694        phone_t *phone = phone_get_current(phone_cap);
     695        if (!phone)
    697696                return ENOENT;
    698697       
  • kernel/generic/src/kobject/kobject.c

    r7e3826d9 r05ffb41  
    3737#include <synch/spinlock.h>
    3838
    39 kobject_t *kobject_get_local(int cap, kobject_type_t type)
     39void kobject_init(kobject_t *kobj)
     40{
     41        kobj->type = KOBJECT_TYPE_INVALID;
     42        kobj->can_reclaim = NULL;
     43}
     44
     45kobject_t *kobject_get(task_t *task, int cap, kobject_type_t type)
    4046{
    4147        if ((cap < 0) || (cap >= MAX_KERNEL_OBJECTS))
    4248                return NULL;
    43         if (TASK->kobject[cap].type != type)
     49        if (task->kobject[cap].type != type)
    4450                return NULL;
    45         return &TASK->kobject[cap];
     51        return &task->kobject[cap];
     52}
     53
     54kobject_t *kobject_get_current(int cap, kobject_type_t type)
     55{
     56        return kobject_get(TASK, cap, type);
    4657}
    4758
     
    5263        irq_spinlock_lock(&task->lock, true);
    5364        for (cap = 0; cap < MAX_KERNEL_OBJECTS; cap++) {
    54                 if (task->kobject[cap].type == KOBJECT_TYPE_INVALID) {
    55                         task->kobject[cap].type = KOBJECT_TYPE_ALLOCATED;
     65                kobject_t *kobj = &task->kobject[cap];
     66                if (kobj->type > KOBJECT_TYPE_ALLOCATED) {
     67                        if (kobj->can_reclaim && kobj->can_reclaim(kobj))
     68                                kobject_init(kobj);
     69                }
     70                if (kobj->type == KOBJECT_TYPE_INVALID) {
     71                        kobj->type = KOBJECT_TYPE_ALLOCATED;
    5672                        irq_spinlock_unlock(&task->lock, true);
    5773                        return cap;
     
    7086
    7187        irq_spinlock_lock(&task->lock, true);
    72         task->kobject[cap].type = KOBJECT_TYPE_INVALID;
     88        kobject_init(&task->kobject[cap]);
    7389        irq_spinlock_unlock(&task->lock, true);
    7490}
  • kernel/generic/src/proc/task.c

    r7e3826d9 r05ffb41  
    166166       
    167167        list_initialize(&task->threads);
     168
     169        int cap;
     170        for (cap = 0; cap < MAX_KERNEL_OBJECTS; cap++)
     171                kobject_init(&task->kobject[cap]);
    168172       
    169173        ipc_answerbox_init(&task->answerbox, task);
    170174       
    171         size_t i;
    172         for (i = 0; i < IPC_MAX_PHONES; i++)
    173                 ipc_phone_init(&task->phones[i], task);
    174 
    175175        spinlock_initialize(&task->active_calls_lock, "active_calls_lock");
    176176        list_initialize(&task->active_calls);
     
    228228       
    229229        if ((ipc_phone_0) &&
    230             (container_check(ipc_phone_0->task->container, task->container)))
    231                 (void) ipc_phone_connect(&task->phones[0], ipc_phone_0);
     230            (container_check(ipc_phone_0->task->container, task->container))) {
     231                int cap = phone_alloc(task);
     232                assert(cap == 0);
     233                (void) ipc_phone_connect(phone_get(task, 0), ipc_phone_0);
     234        }
    232235       
    233236        futex_task_init(task);
     
    611614       
    612615        if (*additional) {
    613                 size_t i;
    614                 for (i = 0; i < IPC_MAX_PHONES; i++) {
    615                         if (task->phones[i].callee)
    616                                 printf(" %zu:%p", i, task->phones[i].callee);
     616                int i;
     617                for (i = 0; i < MAX_KERNEL_OBJECTS; i++) {
     618                        phone_t *phone = phone_get(task, i);
     619                        if (phone && phone->callee)
     620                                printf(" %d:%p", i, phone->callee);
    617621                }
    618622                printf("\n");
Note: See TracChangeset for help on using the changeset viewer.