Changes in / [74a165cc:accdf882] in mainline


Ignore:
Location:
kernel/generic
Files:
19 edited

Legend:

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

    r74a165cc raccdf882  
    3737
    3838#include <abi/cap.h>
     39#include <typedefs.h>
     40#include <adt/list.h>
     41#include <adt/hash.h>
    3942#include <adt/hash_table.h>
    40 #include <adt/hash.h>
    41 #include <adt/list.h>
     43#include <lib/ra.h>
     44#include <synch/mutex.h>
    4245#include <atomic.h>
    43 #include <lib/ra.h>
    44 #include <lib/refcount.h>
    45 #include <synch/mutex.h>
    46 #include <typedefs.h>
    4746
    4847typedef enum {
     
    6059} kobject_type_t;
    6160
    62 struct kobject;
     61struct task;
     62
     63struct call;
     64struct irq;
     65struct phone;
     66struct waitq;
    6367
    6468typedef struct kobject_ops {
    65         void (*destroy)(struct kobject *);
     69        void (*destroy)(void *);
    6670} kobject_ops_t;
    6771
     
    7276/*
    7377 * Everything in kobject_t except for the atomic reference count, the capability
    74  * list and its lock is immutable.
     78 * list and its lock is imutable.
    7579 */
    7680typedef struct kobject {
    7781        kobject_type_t type;
    78         atomic_refcount_t refcnt;
     82        atomic_size_t refcnt;
    7983
    8084        /** Mutex protecting caps_list */
     
    8286        /** List of published capabilities associated with the kobject */
    8387        list_t caps_list;
     88
     89        union {
     90                void *raw;
     91                struct call *call;
     92                struct irq *irq;
     93                struct phone *phone;
     94                struct waitq *waitq;
     95        };
    8496} kobject_t;
    8597
     
    117129extern errno_t caps_task_alloc(struct task *);
    118130extern void caps_task_free(struct task *);
    119 extern void caps_task_clear(struct task *task);
    120 extern errno_t caps_task_init(struct task *);
     131extern void caps_task_init(struct task *);
    121132extern bool caps_apply_to_kobject_type(struct task *, kobject_type_t,
    122133    bool (*)(cap_t *, void *), void *);
     
    128139extern void cap_free(struct task *, cap_handle_t);
    129140
    130 extern void kobject_initialize(kobject_t *, kobject_type_t);
     141extern kobject_t *kobject_alloc(unsigned int);
     142extern void kobject_free(kobject_t *);
     143extern void kobject_initialize(kobject_t *, kobject_type_t, void *);
    131144extern kobject_t *kobject_get(struct task *, cap_handle_t, kobject_type_t);
    132145extern void kobject_add_ref(kobject_t *);
  • kernel/generic/include/ddi/irq.h

    r74a165cc raccdf882  
    132132extern hash_table_t irq_uspace_hash_table;
    133133
     134extern slab_cache_t *irq_cache;
     135
    134136extern inr_t last_inr;
    135137
  • kernel/generic/include/ipc/ipc.h

    r74a165cc raccdf882  
    7474        /** User-defined label */
    7575        sysarg_t label;
    76         kobject_t kobject;
     76        kobject_t *kobject;
    7777} phone_t;
    7878
     
    108108
    109109typedef struct call {
    110         kobject_t kobject;
     110        kobject_t *kobject;
    111111
    112112        /**
     
    169169
    170170extern slab_cache_t *phone_cache;
    171 extern slab_cache_t *irq_cache;
    172171
    173172extern answerbox_t *ipc_box_0;
    174173
    175174extern kobject_ops_t call_kobject_ops;
    176 
    177 static inline phone_t *phone_from_kobject(kobject_t *kobject)
    178 {
    179         if (kobject)
    180                 return ((void *) kobject) - offsetof(phone_t, kobject);
    181         else
    182                 return NULL;
    183 }
    184 
    185 static inline call_t *call_from_kobject(kobject_t *kobject)
    186 {
    187         if (kobject)
    188                 return ((void *) kobject) - offsetof(call_t, kobject);
    189         else
    190                 return NULL;
    191 }
    192175
    193176extern void ipc_init(void);
  • kernel/generic/include/ipc/irq.h

    r74a165cc raccdf882  
    5050extern kobject_ops_t irq_kobject_ops;
    5151
    52 typedef struct {
    53         kobject_t kobject;
    54         irq_t irq;
    55 } irq_kobject_t;
    56 
    57 static inline irq_t *irq_from_kobject(kobject_t *kobject)
    58 {
    59         if (kobject) {
    60                 return &((irq_kobject_t *) kobject)->irq;
    61         } else {
    62                 return NULL;
    63         }
    64 }
    65 
    6652extern irq_ownership_t ipc_irq_top_half_claim(irq_t *);
    6753extern void ipc_irq_top_half_handler(irq_t *);
  • kernel/generic/include/synch/syswaitq.h

    r74a165cc raccdf882  
    4444extern void sys_waitq_init(void);
    4545
     46extern void sys_waitq_task_cleanup(void);
     47
    4648extern sys_errno_t sys_waitq_create(uspace_ptr_cap_waitq_handle_t);
    4749extern sys_errno_t sys_waitq_sleep(cap_waitq_handle_t, uint32_t, unsigned int);
  • kernel/generic/src/cap/cap.c

    r74a165cc raccdf882  
    9393
    9494#define CAPS_START      ((intptr_t) CAP_NIL + 1)
    95 #define CAPS_LAST       ((intptr_t) INT_MAX - 1)
    96 #define CAPS_SIZE       (CAPS_LAST - CAPS_START + 1)
     95#define CAPS_SIZE       (INT_MAX - (int) CAPS_START)
     96#define CAPS_LAST       (CAPS_SIZE - 1)
    9797
    9898static slab_cache_t *cap_cache;
     99static slab_cache_t *kobject_cache;
    99100
    100101kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = {
     
    124125}
    125126
    126 static void caps_remove_callback(ht_link_t *item)
    127 {
    128         cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
    129 
    130         if (cap->kobject) {
    131                 kobject_t *kobj = cap->kobject;
    132 
    133                 mutex_lock(&kobj->caps_list_lock);
    134                 cap->kobject = NULL;
    135                 list_remove(&cap->kobj_link);
    136                 mutex_unlock(&kobj->caps_list_lock);
    137 
    138                 kobject_put(kobj);
    139         }
    140 
    141         list_remove(&cap->type_link);
    142 
    143         slab_free(cap_cache, cap);
    144 }
    145 
    146127static const hash_table_ops_t caps_ops = {
    147128        .hash = caps_hash,
    148129        .key_hash = caps_key_hash,
    149         .key_equal = caps_key_equal,
    150         .remove_callback = caps_remove_callback,
     130        .key_equal = caps_key_equal
    151131};
    152132
     
    155135        cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL,
    156136            NULL, 0);
     137        kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0,
     138            NULL, NULL, 0);
    157139}
    158140
     
    166148        if (!task->cap_info)
    167149                return ENOMEM;
    168 
    169         if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) {
    170                 free(task->cap_info);
    171                 return ENOMEM;
    172         }
    173 
     150        task->cap_info->handles = ra_arena_create();
     151        if (!task->cap_info->handles)
     152                goto error_handles;
     153        if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE))
     154                goto error_span;
     155        if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops))
     156                goto error_span;
     157        return EOK;
     158
     159error_span:
     160        ra_arena_destroy(task->cap_info->handles);
     161error_handles:
     162        free(task->cap_info);
     163        return ENOMEM;
     164}
     165
     166/** Initialize the capability info structure
     167 *
     168 * @param task  Task for which to initialize the info structure.
     169 */
     170void caps_task_init(task_t *task)
     171{
    174172        mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
    175 
    176         task->cap_info->handles = NULL;
    177173
    178174        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
    179175                list_initialize(&task->cap_info->type_list[t]);
    180 
    181         return EOK;
    182 }
    183 
    184 /** Initialize the capability info structure
    185  *
    186  * @param task  Task for which to initialize the info structure.
    187  */
    188 errno_t caps_task_init(task_t *task)
    189 {
    190         assert(task->cap_info);
    191         assert(!task->cap_info->handles);
    192 
    193         task->cap_info->handles = ra_arena_create();
    194         if (!task->cap_info->handles)
    195                 return ENOMEM;
    196 
    197         if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) {
    198                 ra_arena_destroy(task->cap_info->handles);
    199                 return ENOMEM;
    200         }
    201 
    202         return EOK;
    203 }
    204 
    205 void caps_task_clear(task_t *task)
    206 {
    207         mutex_lock(&task->cap_info->lock);
    208 
    209         hash_table_clear(&task->cap_info->caps);
    210 
    211         if (task->cap_info->handles) {
    212                 ra_arena_destroy(task->cap_info->handles);
    213                 task->cap_info->handles = NULL;
    214         }
    215 
    216         for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
    217                 list_initialize(&task->cap_info->type_list[t]);
    218 
    219         mutex_unlock(&task->cap_info->lock);
    220176}
    221177
     
    227183{
    228184        hash_table_destroy(&task->cap_info->caps);
    229 
    230         if (task->cap_info->handles)
    231                 ra_arena_destroy(task->cap_info->handles);
    232 
     185        ra_arena_destroy(task->cap_info->handles);
    233186        free(task->cap_info);
    234187}
     
    347300cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
    348301{
    349         mutex_lock(&task->cap_info->lock);
    350302        mutex_lock(&kobj->caps_list_lock);
     303        mutex_lock(&task->cap_info->lock);
    351304        cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
    352305        assert(cap);
     
    356309        list_append(&cap->kobj_link, &kobj->caps_list);
    357310        list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]);
     311        mutex_unlock(&task->cap_info->lock);
    358312        mutex_unlock(&kobj->caps_list_lock);
    359         mutex_unlock(&task->cap_info->lock);
    360313}
    361314
     
    387340        kobject_t *kobj = NULL;
    388341
     342restart:
    389343        mutex_lock(&task->cap_info->lock);
    390344        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
     
    393347                        /* Hand over cap's reference to kobj */
    394348                        kobj = cap->kobject;
    395 
    396                         mutex_lock(&kobj->caps_list_lock);
     349                        if (mutex_trylock(&kobj->caps_list_lock) != EOK) {
     350                                mutex_unlock(&task->cap_info->lock);
     351                                kobj = NULL;
     352                                goto restart;
     353                        }
    397354                        cap_unpublish_unsafe(cap);
    398355                        mutex_unlock(&kobj->caps_list_lock);
     
    419376{
    420377        mutex_lock(&kobj->caps_list_lock);
    421 
    422         while (!list_empty(&kobj->caps_list)) {
    423                 cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link);
    424 
    425                 /* We're trying to acquire the two locks in reverse order. */
    426                 if (mutex_trylock(&cap->task->cap_info->lock) != EOK) {
    427                         mutex_unlock(&kobj->caps_list_lock);
    428                         mutex_lock(&kobj->caps_list_lock);
    429                         continue;
    430                 }
    431 
     378        list_foreach_safe(kobj->caps_list, cur, hlp) {
     379                cap_t *cap = list_get_instance(cur, cap_t, kobj_link);
     380                mutex_lock(&cap->task->cap_info->lock);
    432381                cap_unpublish_unsafe(cap);
    433382                /* Drop the reference for the unpublished capability */
    434383                kobject_put(kobj);
    435 
    436384                mutex_unlock(&cap->task->cap_info->lock);
    437385        }
    438 
    439386        mutex_unlock(&kobj->caps_list_lock);
    440387}
     
    457404        hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
    458405        ra_free(task->cap_info->handles, cap_handle_raw(handle), 1);
    459         mutex_unlock(&task->cap_info->lock);
     406        slab_free(cap_cache, cap);
     407        mutex_unlock(&task->cap_info->lock);
     408}
     409
     410kobject_t *kobject_alloc(unsigned int flags)
     411{
     412        return slab_alloc(kobject_cache, flags);
     413}
     414
     415void kobject_free(kobject_t *kobj)
     416{
     417        slab_free(kobject_cache, kobj);
    460418}
    461419
     
    464422 * @param kobj  Kernel object to initialize.
    465423 * @param type  Type of the kernel object.
    466  */
    467 void kobject_initialize(kobject_t *kobj, kobject_type_t type)
    468 {
    469         refcount_init(&kobj->refcnt);
     424 * @param raw   Raw pointer to the encapsulated object.
     425 */
     426void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw)
     427{
     428        atomic_store(&kobj->refcnt, 1);
    470429
    471430        mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE);
     
    473432
    474433        kobj->type = type;
     434        kobj->raw = raw;
    475435}
    476436
     
    495455                if (cap->kobject->type == type) {
    496456                        kobj = cap->kobject;
    497                         refcount_up(&kobj->refcnt);
     457                        atomic_inc(&kobj->refcnt);
    498458                }
    499459        }
     
    509469void kobject_add_ref(kobject_t *kobj)
    510470{
    511         refcount_up(&kobj->refcnt);
     471        atomic_inc(&kobj->refcnt);
    512472}
    513473
     
    521481void kobject_put(kobject_t *kobj)
    522482{
    523         if (refcount_down(&kobj->refcnt)) {
    524                 KOBJECT_OP(kobj)->destroy(kobj);
     483        if (atomic_postdec(&kobj->refcnt) == 1) {
     484                KOBJECT_OP(kobj)->destroy(kobj->raw);
     485                kobject_free(kobj);
    525486        }
    526487}
  • kernel/generic/src/ddi/irq.c

    r74a165cc raccdf882  
    5050#include <arch.h>
    5151
     52slab_cache_t *irq_cache = NULL;
     53
    5254/** Spinlock protecting the kernel IRQ hash table
    5355 *
     
    9496{
    9597        last_inr = inrs - 1;
     98
     99        irq_cache = slab_cache_create("irq_t", sizeof(irq_t), 0, NULL, NULL,
     100            FRAME_ATOMIC);
     101        assert(irq_cache);
    96102
    97103        hash_table_create(&irq_uspace_hash_table, chains, 0, &irq_ht_ops);
  • kernel/generic/src/ipc/ipc.c

    r74a165cc raccdf882  
    7171static slab_cache_t *answerbox_cache;
    7272
    73 slab_cache_t *irq_cache = NULL;
    7473slab_cache_t *phone_cache = NULL;
    7574
     
    8887        call->callerbox = NULL;
    8988        call->buffer = NULL;
    90         kobject_initialize(&call->kobject, KOBJECT_TYPE_CALL);
    91 }
    92 
    93 static void call_destroy(kobject_t *arg)
    94 {
    95         call_t *call = call_from_kobject(arg);
     89}
     90
     91static void call_destroy(void *arg)
     92{
     93        call_t *call = (call_t *) arg;
    9694
    9795        if (call->buffer)
    9896                free(call->buffer);
    9997        if (call->caller_phone)
    100                 kobject_put(&call->caller_phone->kobject);
     98                kobject_put(call->caller_phone->kobject);
    10199        slab_free(call_cache, call);
    102100}
     
    116114call_t *ipc_call_alloc(void)
    117115{
     116        // TODO: Allocate call and kobject in single allocation
     117
    118118        call_t *call = slab_alloc(call_cache, FRAME_ATOMIC);
    119119        if (!call)
    120120                return NULL;
    121121
     122        kobject_t *kobj = kobject_alloc(0);
     123        if (!kobj) {
     124                slab_free(call_cache, call);
     125                return NULL;
     126        }
     127
    122128        _ipc_call_init(call);
     129        kobject_initialize(kobj, KOBJECT_TYPE_CALL, call);
     130        call->kobject = kobj;
    123131
    124132        return call;
     
    173181        if (!connected) {
    174182                /* We still have phone->kobject's reference; drop it */
    175                 kobject_put(&phone->kobject);
     183                kobject_put(phone->kobject);
    176184        }
    177185
     
    193201        atomic_store(&phone->active_calls, 0);
    194202        phone->label = 0;
    195         kobject_initialize(&phone->kobject, KOBJECT_TYPE_PHONE);
     203        phone->kobject = NULL;
    196204}
    197205
     
    286294                /* This is a forgotten call and call->sender is not valid. */
    287295                spinlock_unlock(&call->forget_lock);
    288                 kobject_put(&call->kobject);
     296                kobject_put(call->kobject);
    289297                return;
    290298        } else {
     
    344352
    345353        call->caller_phone = phone;
    346         kobject_add_ref(&phone->kobject);
     354        kobject_add_ref(phone->kobject);
    347355
    348356        if (preforget) {
     
    354362                else
    355363                        atomic_inc(&caller->answerbox.active_calls);
    356                 kobject_add_ref(&phone->kobject);
     364                kobject_add_ref(phone->kobject);
    357365                call->sender = caller;
    358366                call->active = true;
     
    471479
    472480                /* Drop the answerbox reference */
    473                 kobject_put(&phone->kobject);
     481                kobject_put(phone->kobject);
    474482
    475483                call_t *call = phone->hangup_call;
     
    573581                atomic_dec(&request->caller_phone->active_calls);
    574582                atomic_dec(&box->active_calls);
    575                 kobject_put(&request->caller_phone->kobject);
     583                kobject_put(request->caller_phone->kobject);
    576584        } else if (!list_empty(&box->calls)) {
    577585                /* Count received call */
     
    689697                        task_release(phone->caller);
    690698
    691                         kobject_put(&phone->kobject);
     699                        kobject_put(phone->kobject);
    692700
    693701                        /* Must start again */
     
    696704
    697705                mutex_unlock(&phone->lock);
    698                 kobject_put(&phone->kobject);
     706                kobject_put(phone->kobject);
    699707        }
    700708
     
    720728         * must hold a reference to it.
    721729         */
    722         kobject_add_ref(&call->kobject);
     730        kobject_add_ref(call->kobject);
    723731
    724732        spinlock_unlock(&call->forget_lock);
     
    727735        atomic_dec(&call->caller_phone->active_calls);
    728736        atomic_dec(&TASK->answerbox.active_calls);
    729         kobject_put(&call->caller_phone->kobject);
     737        kobject_put(call->caller_phone->kobject);
    730738
    731739        SYSIPC_OP(request_forget, call);
    732740
    733         kobject_put(&call->kobject);
     741        kobject_put(call->kobject);
    734742}
    735743
     
    769777static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
    770778{
    771         ipc_phone_hangup(phone_from_kobject(cap->kobject));
     779        ipc_phone_hangup(cap->kobject->phone);
    772780        kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
    773781            KOBJECT_TYPE_PHONE);
     
    790798                SYSIPC_OP(answer_process, call);
    791799
    792                 kobject_put(&call->kobject);
     800                kobject_put(call->kobject);
    793801
    794802                /*
     
    884892        answerbox_cache = slab_cache_create("answerbox_t", sizeof(answerbox_t),
    885893            0, NULL, NULL, 0);
    886         irq_cache = slab_cache_create("irq_t", sizeof(irq_kobject_t),
    887             0, NULL, NULL, 0);
    888894}
    889895
     
    921927static bool print_task_phone_cb(cap_t *cap, void *arg)
    922928{
    923         phone_t *phone = phone_from_kobject(cap->kobject);
     929        phone_t *phone = cap->kobject->phone;
    924930
    925931        mutex_lock(&phone->lock);
  • kernel/generic/src/ipc/ipcrsc.c

    r74a165cc raccdf882  
    4444#include <stdlib.h>
    4545
    46 static void phone_destroy(kobject_t *arg)
     46static void phone_destroy(void *arg)
    4747{
    48         phone_t *phone = phone_from_kobject(arg);
     48        phone_t *phone = (phone_t *) arg;
    4949        if (phone->hangup_call)
    50                 kobject_put(&phone->hangup_call->kobject);
     50                kobject_put(phone->hangup_call->kobject);
    5151        slab_free(phone_cache, phone);
    5252}
     
    7676                        return ENOMEM;
    7777                }
    78 
     78                kobject_t *kobj = kobject_alloc(FRAME_ATOMIC);
     79                if (!kobj) {
     80                        cap_free(TASK, handle);
     81                        slab_free(phone_cache, phone);
     82                        return ENOMEM;
     83                }
    7984                call_t *hcall = ipc_call_alloc();
    8085                if (!hcall) {
    8186                        cap_free(TASK, handle);
    8287                        slab_free(phone_cache, phone);
     88                        free(kobj);
    8389                        return ENOMEM;
    8490                }
     
    8894                phone->hangup_call = hcall;
    8995
     96                kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone);
     97                phone->kobject = kobj;
     98
    9099                if (publish)
    91                         cap_publish(task, handle, &phone->kobject);
     100                        cap_publish(task, handle, kobj);
    92101
    93102                *phandle = handle;
    94103                if (kobject)
    95                         *kobject = &phone->kobject;
     104                        *kobject = kobj;
    96105        }
    97106        return rc;
  • kernel/generic/src/ipc/irq.c

    r74a165cc raccdf882  
    295295}
    296296
    297 static void irq_destroy(kobject_t *arg)
    298 {
    299         irq_kobject_t *kobj = (irq_kobject_t *) arg;
    300 
    301         irq_hash_out(&kobj->irq);
     297static void irq_destroy(void *arg)
     298{
     299        irq_t *irq = (irq_t *) arg;
     300
     301        irq_hash_out(irq);
    302302
    303303        /* Free up the IRQ code and associated structures. */
    304         code_free(kobj->irq.notif_cfg.code);
    305         slab_free(irq_cache, kobj);
     304        code_free(irq->notif_cfg.code);
     305        slab_free(irq_cache, irq);
    306306}
    307307
     
    350350        }
    351351
    352         irq_kobject_t *kobj = slab_alloc(irq_cache, FRAME_ATOMIC);
    353         if (!kobj) {
     352        irq_t *irq = (irq_t *) slab_alloc(irq_cache, FRAME_ATOMIC);
     353        if (!irq) {
    354354                cap_free(TASK, handle);
    355355                return ENOMEM;
    356356        }
    357357
    358         kobject_initialize(&kobj->kobject, KOBJECT_TYPE_IRQ);
    359 
    360         irq_t *irq = &kobj->irq;
     358        kobject_t *kobject = kobject_alloc(FRAME_ATOMIC);
     359        if (!kobject) {
     360                cap_free(TASK, handle);
     361                slab_free(irq_cache, irq);
     362                return ENOMEM;
     363        }
    361364
    362365        irq_initialize(irq);
     
    382385        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    383386
    384         cap_publish(TASK, handle, &kobj->kobject);
     387        kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq);
     388        cap_publish(TASK, handle, kobject);
    385389
    386390        return EOK;
     
    401405                return ENOENT;
    402406
    403         assert(irq_from_kobject(kobj)->notif_cfg.answerbox == box);
    404 
    405         irq_hash_out(irq_from_kobject(kobj));
     407        assert(kobj->irq->notif_cfg.answerbox == box);
     408
     409        irq_hash_out(kobj->irq);
    406410
    407411        kobject_put(kobj);
  • kernel/generic/src/ipc/kbox.c

    r74a165cc raccdf882  
    242242        }
    243243
    244         phone_t *phone = phone_from_kobject(
    245             kobject_get(TASK, phone_handle, KOBJECT_TYPE_PHONE));
     244        kobject_t *phone_obj = kobject_get(TASK, phone_handle,
     245            KOBJECT_TYPE_PHONE);
    246246        /* Connect the newly allocated phone to the kbox */
    247247        /* Hand over phone_obj's reference to ipc_phone_connect() */
    248         (void) ipc_phone_connect(phone, &task->kb.box);
     248        (void) ipc_phone_connect(phone_obj->phone, &task->kb.box);
    249249
    250250        mutex_unlock(&task->kb.cleanup_lock);
  • kernel/generic/src/ipc/ops/conctmeto.c

    r74a165cc raccdf882  
    8888
    8989        /* Set the recipient-assigned label */
    90         phone_from_kobject(pobj)->label = ipc_get_arg5(&answer->data);
     90        pobj->phone->label = ipc_get_arg5(&answer->data);
    9191
    9292        /* Restore phone handle in answer's ARG5 */
     
    9696        if (ipc_get_retval(&answer->data) == EOK) {
    9797                /* Hand over reference from pobj to the answerbox */
    98                 (void) ipc_phone_connect(phone_from_kobject(pobj), &TASK->answerbox);
     98                (void) ipc_phone_connect(pobj->phone, &TASK->answerbox);
    9999        } else {
    100100                /* Drop the extra reference */
  • kernel/generic/src/ipc/ops/concttome.c

    r74a165cc raccdf882  
    4949                 * Set the sender-assigned label to the new phone.
    5050                 */
    51                 phone_from_kobject(pobj)->label = ipc_get_arg5(&call->data);
     51                pobj->phone->label = ipc_get_arg5(&call->data);
    5252        }
    5353        call->priv = (sysarg_t) pobj;
     
    8888                kobject_add_ref(pobj);
    8989
    90                 if (ipc_phone_connect(phone_from_kobject(pobj),
     90                if (ipc_phone_connect(pobj->phone,
    9191                    &answer->sender->answerbox)) {
    9292                        /* Pass the reference to the capability */
  • kernel/generic/src/ipc/ops/stchngath.c

    r74a165cc raccdf882  
    4545        task_t *other_task_s;
    4646
    47         phone_t *sender_phone = phone_from_kobject(kobject_get(TASK,
    48             (cap_handle_t) ipc_get_arg5(&call->data), KOBJECT_TYPE_PHONE));
    49         if (!sender_phone)
     47        kobject_t *sender_obj = kobject_get(TASK,
     48            (cap_handle_t) ipc_get_arg5(&call->data), KOBJECT_TYPE_PHONE);
     49        if (!sender_obj)
    5050                return ENOENT;
    5151
    52         mutex_lock(&sender_phone->lock);
    53         if (sender_phone->state != IPC_PHONE_CONNECTED) {
    54                 mutex_unlock(&sender_phone->lock);
    55                 kobject_put(&sender_phone->kobject);
     52        mutex_lock(&sender_obj->phone->lock);
     53        if (sender_obj->phone->state != IPC_PHONE_CONNECTED) {
     54                mutex_unlock(&sender_obj->phone->lock);
     55                kobject_put(sender_obj);
    5656                return EINVAL;
    5757        }
    5858
    59         other_task_s = sender_phone->callee->task;
     59        other_task_s = sender_obj->phone->callee->task;
    6060
    61         mutex_unlock(&sender_phone->lock);
     61        mutex_unlock(&sender_obj->phone->lock);
    6262
    6363        /* Remember the third party task hash. */
    6464        ipc_set_arg5(&call->data, (sysarg_t) other_task_s);
    6565
    66         kobject_put(&sender_phone->kobject);
     66        kobject_put(sender_obj);
    6767        return EOK;
    6868}
     
    7777                task_t *other_task_r;
    7878
    79                 phone_t *recipient_phone = phone_from_kobject(kobject_get(TASK,
     79                kobject_t *recipient_obj = kobject_get(TASK,
    8080                    (cap_handle_t) ipc_get_arg1(&answer->data),
    81                     KOBJECT_TYPE_PHONE));
    82                 if (!recipient_phone) {
     81                    KOBJECT_TYPE_PHONE);
     82                if (!recipient_obj) {
    8383                        ipc_set_retval(&answer->data, ENOENT);
    8484                        return ENOENT;
    8585                }
    8686
    87                 mutex_lock(&recipient_phone->lock);
    88                 if (recipient_phone->state != IPC_PHONE_CONNECTED) {
    89                         mutex_unlock(&recipient_phone->lock);
     87                mutex_lock(&recipient_obj->phone->lock);
     88                if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
     89                        mutex_unlock(&recipient_obj->phone->lock);
    9090                        ipc_set_retval(&answer->data, EINVAL);
    91                         kobject_put(&recipient_phone->kobject);
     91                        kobject_put(recipient_obj);
    9292                        return EINVAL;
    9393                }
    9494
    95                 other_task_r = recipient_phone->callee->task;
     95                other_task_r = recipient_obj->phone->callee->task;
    9696                other_task_s = (task_t *) ipc_get_arg5(olddata);
    9797
     
    114114                }
    115115
    116                 mutex_unlock(&recipient_phone->lock);
    117                 kobject_put(&recipient_phone->kobject);
     116                mutex_unlock(&recipient_obj->phone->lock);
     117                kobject_put(recipient_obj);
    118118        }
    119119
  • kernel/generic/src/ipc/sysipc.c

    r74a165cc raccdf882  
    199199                        list_remove(&phone->link);
    200200                        /* Drop callee->connected_phones reference */
    201                         kobject_put(&phone->kobject);
     201                        kobject_put(phone->kobject);
    202202                        phone->state = IPC_PHONE_SLAMMED;
    203203                        phone->label = 0;
     
    273273ipc_req_internal(cap_phone_handle_t handle, ipc_data_t *data, sysarg_t priv)
    274274{
    275         phone_t *phone = phone_from_kobject(
    276             kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
    277         if (!phone)
     275        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     276        if (!kobj->phone)
    278277                return ENOENT;
    279278
    280279        call_t *call = ipc_call_alloc();
    281280        if (!call) {
    282                 kobject_put(&phone->kobject);
     281                kobject_put(kobj);
    283282                return ENOMEM;
    284283        }
     
    287286        memcpy(call->data.args, data->args, sizeof(data->args));
    288287
    289         errno_t rc = request_preprocess(call, phone);
     288        errno_t rc = request_preprocess(call, kobj->phone);
    290289        if (!rc) {
    291290#ifdef CONFIG_UDEBUG
     
    293292#endif
    294293
    295                 kobject_add_ref(&call->kobject);
    296                 rc = ipc_call_sync(phone, call);
     294                kobject_add_ref(call->kobject);
     295                rc = ipc_call_sync(kobj->phone, call);
    297296                spinlock_lock(&call->forget_lock);
    298297                bool forgotten = call->forget;
    299298                spinlock_unlock(&call->forget_lock);
    300                 kobject_put(&call->kobject);
     299                kobject_put(call->kobject);
    301300
    302301#ifdef CONFIG_UDEBUG
     
    313312                                 * deallocation.
    314313                                 */
    315                                 kobject_put(&call->kobject);
     314                                kobject_put(call->kobject);
    316315                        } else {
    317316                                /*
     
    321320                                assert(rc == EINTR);
    322321                        }
    323                         kobject_put(&phone->kobject);
     322                        kobject_put(kobj);
    324323                        return rc;
    325324                }
     
    330329
    331330        memcpy(data->args, call->data.args, sizeof(data->args));
    332         kobject_put(&call->kobject);
    333         kobject_put(&phone->kobject);
     331        kobject_put(call->kobject);
     332        kobject_put(kobj);
    334333
    335334        return EOK;
     
    371370    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t label)
    372371{
    373         phone_t *phone = phone_from_kobject(
    374             kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
    375 
    376         if (!phone)
     372        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     373        if (!kobj)
    377374                return ENOENT;
    378375
    379         if (check_call_limit(phone)) {
    380                 kobject_put(&phone->kobject);
     376        if (check_call_limit(kobj->phone)) {
     377                kobject_put(kobj);
    381378                return ELIMIT;
    382379        }
     
    384381        call_t *call = ipc_call_alloc();
    385382        if (!call) {
    386                 kobject_put(&phone->kobject);
     383                kobject_put(kobj);
    387384                return ENOMEM;
    388385        }
     
    402399        call->data.answer_label = label;
    403400
    404         errno_t res = request_preprocess(call, phone);
     401        errno_t res = request_preprocess(call, kobj->phone);
    405402
    406403        if (!res)
    407                 ipc_call(phone, call);
     404                ipc_call(kobj->phone, call);
    408405        else
    409                 ipc_backsend_err(phone, call, res);
    410 
    411         kobject_put(&phone->kobject);
     406                ipc_backsend_err(kobj->phone, call, res);
     407
     408        kobject_put(kobj);
    412409        return EOK;
    413410}
     
    425422    sysarg_t label)
    426423{
    427         phone_t *phone = phone_from_kobject(
    428             kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
    429         if (!phone)
     424        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     425        if (!kobj)
    430426                return ENOENT;
    431427
    432         if (check_call_limit(phone)) {
    433                 kobject_put(&phone->kobject);
     428        if (check_call_limit(kobj->phone)) {
     429                kobject_put(kobj);
    434430                return ELIMIT;
    435431        }
     
    437433        call_t *call = ipc_call_alloc();
    438434        if (!call) {
    439                 kobject_put(&phone->kobject);
     435                kobject_put(kobj);
    440436                return ENOMEM;
    441437        }
     
    444440            sizeof(call->data.args));
    445441        if (rc != EOK) {
    446                 kobject_put(&call->kobject);
    447                 kobject_put(&phone->kobject);
     442                kobject_put(call->kobject);
     443                kobject_put(kobj);
    448444                return (sys_errno_t) rc;
    449445        }
     
    452448        call->data.answer_label = label;
    453449
    454         errno_t res = request_preprocess(call, phone);
     450        errno_t res = request_preprocess(call, kobj->phone);
    455451
    456452        if (!res)
    457                 ipc_call(phone, call);
     453                ipc_call(kobj->phone, call);
    458454        else
    459                 ipc_backsend_err(phone, call, res);
    460 
    461         kobject_put(&phone->kobject);
     455                ipc_backsend_err(kobj->phone, call, res);
     456
     457        kobject_put(kobj);
    462458        return EOK;
    463459}
     
    493489                return ENOENT;
    494490
    495         call_t *call = call_from_kobject(ckobj);
     491        call_t *call = ckobj->call;
    496492
    497493        ipc_data_t old;
     
    555551        }
    556552
    557         rc = ipc_forward(call, phone_from_kobject(pkobj), &TASK->answerbox, mode);
     553        rc = ipc_forward(call, pkobj->phone, &TASK->answerbox, mode);
    558554        if (rc != EOK) {
    559555                after_forward = true;
     
    663659                return ENOENT;
    664660
    665         call_t *call = call_from_kobject(kobj);
     661        call_t *call = kobj->call;
    666662        assert(!(call->flags & IPC_CALL_ANSWERED));
    667663
     
    710706                return ENOENT;
    711707
    712         call_t *call = call_from_kobject(kobj);
     708        call_t *call = kobj->call;
    713709        assert(!(call->flags & IPC_CALL_ANSWERED));
    714710
     
    755751                return ENOENT;
    756752
    757         errno_t rc = ipc_phone_hangup(phone_from_kobject(kobj));
     753        errno_t rc = ipc_phone_hangup(kobj->phone);
    758754        kobject_put(kobj);
    759755        cap_free(TASK, handle);
     
    801797
    802798                STRUCT_TO_USPACE(calldata, &call->data);
    803                 kobject_put(&call->kobject);
     799                kobject_put(call->kobject);
    804800
    805801                return EOK;
     
    810806
    811807                if (call->flags & IPC_CALL_DISCARD_ANSWER) {
    812                         kobject_put(&call->kobject);
     808                        kobject_put(call->kobject);
    813809                        goto restart;
    814810                }
     
    817813
    818814                STRUCT_TO_USPACE(calldata, &call->data);
    819                 kobject_put(&call->kobject);
     815                kobject_put(call->kobject);
    820816
    821817                return EOK;
     
    840836                goto error;
    841837
    842         kobject_add_ref(&call->kobject);
    843         cap_publish(TASK, handle, &call->kobject);
     838        kobject_add_ref(call->kobject);
     839        cap_publish(TASK, handle, call->kobject);
    844840        return EOK;
    845841
  • kernel/generic/src/proc/task.c

    r74a165cc raccdf882  
    201201                return NULL;
    202202
    203         if (caps_task_init(task) != EOK) {
    204                 slab_free(task_cache, task);
    205                 return NULL;
    206         }
    207 
    208203        refcount_init(&task->refcount);
    209204
     
    217212        task->ucycles = 0;
    218213        task->kcycles = 0;
     214
     215        caps_task_init(task);
    219216
    220217        task->ipc_info.call_sent = 0;
     
    251248                }
    252249
    253                 phone_t *phone = phone_from_kobject(
    254                     kobject_get(task, phone_handle, KOBJECT_TYPE_PHONE));
    255                 (void) ipc_phone_connect(phone, ipc_box_0);
     250                kobject_t *phone_obj = kobject_get(task, phone_handle,
     251                    KOBJECT_TYPE_PHONE);
     252                (void) ipc_phone_connect(phone_obj->phone, ipc_box_0);
    256253        }
    257254
     
    290287         */
    291288        as_release(task->as);
    292 
    293         caps_task_clear(task);
    294289
    295290        slab_free(task_cache, task);
  • kernel/generic/src/proc/thread.c

    r74a165cc raccdf882  
    444444                         */
    445445                        ipc_cleanup();
    446                         caps_task_clear(TASK);
     446                        sys_waitq_task_cleanup();
    447447                        LOG("Cleanup of task %" PRIu64 " completed.", TASK->taskid);
    448448                }
  • kernel/generic/src/synch/syswaitq.c

    r74a165cc raccdf882  
    4848static slab_cache_t *waitq_cache;
    4949
    50 typedef struct {
    51         kobject_t kobject;
    52         waitq_t waitq;
    53 } waitq_kobject_t;
    54 
    55 static void waitq_destroy(kobject_t *arg)
     50static void waitq_destroy(void *arg)
    5651{
    57         waitq_kobject_t *wq = (waitq_kobject_t *) arg;
     52        waitq_t *wq = (waitq_t *) arg;
    5853        slab_free(waitq_cache, wq);
    5954}
    6055
    6156kobject_ops_t waitq_kobject_ops = {
    62         .destroy = waitq_destroy,
     57        .destroy = waitq_destroy
    6358};
     59
     60static bool waitq_cap_cleanup_cb(cap_t *cap, void *arg)
     61{
     62        kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
     63            KOBJECT_TYPE_WAITQ);
     64        kobject_put(kobj);
     65        cap_free(cap->task, cap->handle);
     66        return true;
     67}
    6468
    6569/** Initialize the user waitq subsystem */
    6670void sys_waitq_init(void)
    6771{
    68         waitq_cache = slab_cache_create("syswaitq_t", sizeof(waitq_kobject_t),
    69             0, NULL, NULL, 0);
     72        waitq_cache = slab_cache_create("waitq_t", sizeof(waitq_t), 0, NULL,
     73            NULL, 0);
     74}
     75
     76/** Clean-up all waitq capabilities held by the exiting task */
     77void sys_waitq_task_cleanup(void)
     78{
     79        caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_WAITQ,
     80            waitq_cap_cleanup_cb, NULL);
    7081}
    7182
     
    7990sys_errno_t sys_waitq_create(uspace_ptr_cap_waitq_handle_t whandle)
    8091{
    81         waitq_kobject_t *kobj = slab_alloc(waitq_cache, FRAME_ATOMIC);
    82         if (!kobj)
     92        waitq_t *wq = slab_alloc(waitq_cache, FRAME_ATOMIC);
     93        if (!wq)
    8394                return (sys_errno_t) ENOMEM;
     95        waitq_initialize(wq);
    8496
    85         kobject_initialize(&kobj->kobject, KOBJECT_TYPE_WAITQ);
    86         waitq_initialize(&kobj->waitq);
     97        kobject_t *kobj = kobject_alloc(0);
     98        if (!kobj) {
     99                slab_free(waitq_cache, wq);
     100                return (sys_errno_t) ENOMEM;
     101        }
     102        kobject_initialize(kobj, KOBJECT_TYPE_WAITQ, wq);
    87103
    88104        cap_handle_t handle;
    89105        errno_t rc = cap_alloc(TASK, &handle);
    90106        if (rc != EOK) {
    91                 slab_free(waitq_cache, kobj);
     107                slab_free(waitq_cache, wq);
     108                kobject_free(kobj);
    92109                return (sys_errno_t) rc;
    93110        }
     
    96113        if (rc != EOK) {
    97114                cap_free(TASK, handle);
    98                 slab_free(waitq_cache, kobj);
     115                kobject_free(kobj);
     116                slab_free(waitq_cache, wq);
    99117                return (sys_errno_t) rc;
    100118        }
    101119
    102         cap_publish(TASK, handle, &kobj->kobject);
     120        cap_publish(TASK, handle, kobj);
    103121
    104122        return (sys_errno_t) EOK;
     
    133151    unsigned int flags)
    134152{
    135         waitq_kobject_t *kobj =
    136             (waitq_kobject_t *) kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
     153        kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
    137154        if (!kobj)
    138155                return (sys_errno_t) ENOENT;
     
    142159#endif
    143160
    144         errno_t rc = _waitq_sleep_timeout(&kobj->waitq, timeout,
     161        errno_t rc = _waitq_sleep_timeout(kobj->waitq, timeout,
    145162            SYNCH_FLAGS_INTERRUPTIBLE | flags);
    146163
     
    149166#endif
    150167
    151         kobject_put(&kobj->kobject);
     168        kobject_put(kobj);
    152169
    153170        return (sys_errno_t) rc;
     
    162179sys_errno_t sys_waitq_wakeup(cap_waitq_handle_t whandle)
    163180{
    164         waitq_kobject_t *kobj =
    165             (waitq_kobject_t *) kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
     181        kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
    166182        if (!kobj)
    167183                return (sys_errno_t) ENOENT;
    168184
    169         waitq_wake_one(&kobj->waitq);
     185        waitq_wake_one(kobj->waitq);
    170186
    171         kobject_put(&kobj->kobject);
     187        kobject_put(kobj);
    172188        return (sys_errno_t) EOK;
    173189}
  • kernel/generic/src/sysinfo/stats.c

    r74a165cc raccdf882  
    384384static bool produce_stats_ipcc_cb(cap_t *cap, void *arg)
    385385{
    386         phone_t *phone = (phone_t *) cap->kobject;
     386        phone_t *phone = cap->kobject->phone;
    387387        ipccs_state_t *state = (ipccs_state_t *) arg;
    388388
Note: See TracChangeset for help on using the changeset viewer.