Changeset 6caf5fb in mainline


Ignore:
Timestamp:
2025-01-16T21:42:15Z (12 hours ago)
Author:
GitHub <noreply@…>
Parents:
e0e2264 (diff), 455241b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-01-16 21:42:15)
git-committer:
GitHub <noreply@…> (2025-01-16 21:42:15)
Message:

Merge 455241b37bedd3719ed3b5b025fdf26f44fd565b into e0e22648f5799cc98671695e153b0b00037daeb9

Location:
kernel/generic
Files:
19 edited

Legend:

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

    re0e2264 r6caf5fb  
    3737
    3838#include <abi/cap.h>
     39#include <adt/hash_table.h>
     40#include <adt/hash.h>
     41#include <adt/list.h>
     42#include <atomic.h>
     43#include <lib/ra.h>
     44#include <lib/refcount.h>
     45#include <synch/mutex.h>
    3946#include <typedefs.h>
    40 #include <adt/list.h>
    41 #include <adt/hash.h>
    42 #include <adt/hash_table.h>
    43 #include <lib/ra.h>
    44 #include <synch/mutex.h>
    45 #include <atomic.h>
    4647
    4748typedef enum {
     
    5960} kobject_type_t;
    6061
    61 struct task;
    62 
    63 struct call;
    64 struct irq;
    65 struct phone;
    66 struct waitq;
     62struct kobject;
    6763
    6864typedef struct kobject_ops {
    69         void (*destroy)(void *);
     65        void (*destroy)(struct kobject *);
    7066} kobject_ops_t;
    7167
     
    7672/*
    7773 * Everything in kobject_t except for the atomic reference count, the capability
    78  * list and its lock is imutable.
     74 * list and its lock is immutable.
    7975 */
    8076typedef struct kobject {
    8177        kobject_type_t type;
    82         atomic_size_t refcnt;
     78        atomic_refcount_t refcnt;
    8379
    8480        /** Mutex protecting caps_list */
     
    8682        /** List of published capabilities associated with the kobject */
    8783        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         };
    9684} kobject_t;
    9785
     
    129117extern errno_t caps_task_alloc(struct task *);
    130118extern void caps_task_free(struct task *);
    131 extern void caps_task_init(struct task *);
     119extern void caps_task_clear(struct task *task);
     120extern errno_t caps_task_init(struct task *);
    132121extern bool caps_apply_to_kobject_type(struct task *, kobject_type_t,
    133122    bool (*)(cap_t *, void *), void *);
     
    139128extern void cap_free(struct task *, cap_handle_t);
    140129
    141 extern kobject_t *kobject_alloc(unsigned int);
    142 extern void kobject_free(kobject_t *);
    143 extern void kobject_initialize(kobject_t *, kobject_type_t, void *);
     130extern void kobject_initialize(kobject_t *, kobject_type_t);
    144131extern kobject_t *kobject_get(struct task *, cap_handle_t, kobject_type_t);
    145132extern void kobject_add_ref(kobject_t *);
  • kernel/generic/include/ddi/irq.h

    re0e2264 r6caf5fb  
    132132extern hash_table_t irq_uspace_hash_table;
    133133
    134 extern slab_cache_t *irq_cache;
    135 
    136134extern inr_t last_inr;
    137135
  • kernel/generic/include/ipc/ipc.h

    re0e2264 r6caf5fb  
    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;
     171extern slab_cache_t *irq_cache;
    171172
    172173extern answerbox_t *ipc_box_0;
    173174
    174175extern kobject_ops_t call_kobject_ops;
     176
     177static 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
     185static 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}
    175192
    176193extern void ipc_init(void);
  • kernel/generic/include/ipc/irq.h

    re0e2264 r6caf5fb  
    5050extern kobject_ops_t irq_kobject_ops;
    5151
     52typedef struct {
     53        kobject_t kobject;
     54        irq_t irq;
     55} irq_kobject_t;
     56
     57static 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
    5266extern irq_ownership_t ipc_irq_top_half_claim(irq_t *);
    5367extern void ipc_irq_top_half_handler(irq_t *);
  • kernel/generic/include/synch/syswaitq.h

    re0e2264 r6caf5fb  
    4444extern void sys_waitq_init(void);
    4545
    46 extern void sys_waitq_task_cleanup(void);
    47 
    4846extern sys_errno_t sys_waitq_create(uspace_ptr_cap_waitq_handle_t);
    4947extern sys_errno_t sys_waitq_sleep(cap_waitq_handle_t, uint32_t, unsigned int);
  • kernel/generic/src/cap/cap.c

    re0e2264 r6caf5fb  
    9393
    9494#define CAPS_START      ((intptr_t) CAP_NIL + 1)
    95 #define CAPS_SIZE       (INT_MAX - (int) CAPS_START)
    96 #define CAPS_LAST       (CAPS_SIZE - 1)
     95#define CAPS_LAST       ((intptr_t) INT_MAX - 1)
     96#define CAPS_SIZE       (CAPS_LAST - CAPS_START + 1)
    9797
    9898static slab_cache_t *cap_cache;
    99 static slab_cache_t *kobject_cache;
    10099
    101100kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = {
     
    125124}
    126125
     126static 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
    127146static const hash_table_ops_t caps_ops = {
    128147        .hash = caps_hash,
    129148        .key_hash = caps_key_hash,
    130         .key_equal = caps_key_equal
     149        .key_equal = caps_key_equal,
     150        .remove_callback = caps_remove_callback,
    131151};
    132152
     
    135155        cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL,
    136156            NULL, 0);
    137         kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0,
    138             NULL, NULL, 0);
    139157}
    140158
     
    148166        if (!task->cap_info)
    149167                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
     174        mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
     175
     176        task->cap_info->handles = NULL;
     177
     178        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
     179                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 */
     188errno_t caps_task_init(task_t *task)
     189{
     190        assert(task->cap_info);
     191        assert(!task->cap_info->handles);
     192
    150193        task->cap_info->handles = ra_arena_create();
    151194        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;
     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
    157202        return EOK;
    158 
    159 error_span:
    160         ra_arena_destroy(task->cap_info->handles);
    161 error_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  */
    170 void caps_task_init(task_t *task)
    171 {
    172         mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
     203}
     204
     205void 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        }
    173215
    174216        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
    175217                list_initialize(&task->cap_info->type_list[t]);
     218
     219        mutex_unlock(&task->cap_info->lock);
    176220}
    177221
     
    183227{
    184228        hash_table_destroy(&task->cap_info->caps);
    185         ra_arena_destroy(task->cap_info->handles);
     229
     230        if (task->cap_info->handles)
     231                ra_arena_destroy(task->cap_info->handles);
     232
    186233        free(task->cap_info);
    187234}
     
    300347cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
    301348{
     349        mutex_lock(&task->cap_info->lock);
    302350        mutex_lock(&kobj->caps_list_lock);
    303         mutex_lock(&task->cap_info->lock);
    304351        cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
    305352        assert(cap);
     
    309356        list_append(&cap->kobj_link, &kobj->caps_list);
    310357        list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]);
    311         mutex_unlock(&task->cap_info->lock);
    312358        mutex_unlock(&kobj->caps_list_lock);
     359        mutex_unlock(&task->cap_info->lock);
    313360}
    314361
     
    340387        kobject_t *kobj = NULL;
    341388
    342 restart:
    343389        mutex_lock(&task->cap_info->lock);
    344390        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
     
    347393                        /* Hand over cap's reference to kobj */
    348394                        kobj = cap->kobject;
    349                         if (mutex_trylock(&kobj->caps_list_lock) != EOK) {
    350                                 mutex_unlock(&task->cap_info->lock);
    351                                 kobj = NULL;
    352                                 goto restart;
    353                         }
     395
     396                        mutex_lock(&kobj->caps_list_lock);
    354397                        cap_unpublish_unsafe(cap);
    355398                        mutex_unlock(&kobj->caps_list_lock);
     
    376419{
    377420        mutex_lock(&kobj->caps_list_lock);
    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);
     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
    381432                cap_unpublish_unsafe(cap);
    382433                /* Drop the reference for the unpublished capability */
    383434                kobject_put(kobj);
     435
    384436                mutex_unlock(&cap->task->cap_info->lock);
    385437        }
     438
    386439        mutex_unlock(&kobj->caps_list_lock);
    387440}
     
    404457        hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
    405458        ra_free(task->cap_info->handles, cap_handle_raw(handle), 1);
    406         slab_free(cap_cache, cap);
    407         mutex_unlock(&task->cap_info->lock);
    408 }
    409 
    410 kobject_t *kobject_alloc(unsigned int flags)
    411 {
    412         return slab_alloc(kobject_cache, flags);
    413 }
    414 
    415 void kobject_free(kobject_t *kobj)
    416 {
    417         slab_free(kobject_cache, kobj);
     459        mutex_unlock(&task->cap_info->lock);
    418460}
    419461
     
    422464 * @param kobj  Kernel object to initialize.
    423465 * @param type  Type of the kernel object.
    424  * @param raw   Raw pointer to the encapsulated object.
    425  */
    426 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw)
    427 {
    428         atomic_store(&kobj->refcnt, 1);
     466 */
     467void kobject_initialize(kobject_t *kobj, kobject_type_t type)
     468{
     469        refcount_init(&kobj->refcnt);
    429470
    430471        mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE);
     
    432473
    433474        kobj->type = type;
    434         kobj->raw = raw;
    435475}
    436476
     
    455495                if (cap->kobject->type == type) {
    456496                        kobj = cap->kobject;
    457                         atomic_inc(&kobj->refcnt);
     497                        refcount_up(&kobj->refcnt);
    458498                }
    459499        }
     
    469509void kobject_add_ref(kobject_t *kobj)
    470510{
    471         atomic_inc(&kobj->refcnt);
     511        refcount_up(&kobj->refcnt);
    472512}
    473513
     
    481521void kobject_put(kobject_t *kobj)
    482522{
    483         if (atomic_postdec(&kobj->refcnt) == 1) {
    484                 KOBJECT_OP(kobj)->destroy(kobj->raw);
    485                 kobject_free(kobj);
     523        if (refcount_down(&kobj->refcnt)) {
     524                KOBJECT_OP(kobj)->destroy(kobj);
    486525        }
    487526}
  • kernel/generic/src/ddi/irq.c

    re0e2264 r6caf5fb  
    5050#include <arch.h>
    5151
    52 slab_cache_t *irq_cache = NULL;
    53 
    5452/** Spinlock protecting the kernel IRQ hash table
    5553 *
     
    9694{
    9795        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);
    10296
    10397        hash_table_create(&irq_uspace_hash_table, chains, 0, &irq_ht_ops);
  • kernel/generic/src/ipc/ipc.c

    re0e2264 r6caf5fb  
    7171static slab_cache_t *answerbox_cache;
    7272
     73slab_cache_t *irq_cache = NULL;
    7374slab_cache_t *phone_cache = NULL;
    7475
     
    8788        call->callerbox = NULL;
    8889        call->buffer = NULL;
    89 }
    90 
    91 static void call_destroy(void *arg)
    92 {
    93         call_t *call = (call_t *) arg;
     90        kobject_initialize(&call->kobject, KOBJECT_TYPE_CALL);
     91}
     92
     93static void call_destroy(kobject_t *arg)
     94{
     95        call_t *call = call_from_kobject(arg);
    9496
    9597        if (call->buffer)
    9698                free(call->buffer);
    9799        if (call->caller_phone)
    98                 kobject_put(call->caller_phone->kobject);
     100                kobject_put(&call->caller_phone->kobject);
    99101        slab_free(call_cache, call);
    100102}
     
    114116call_t *ipc_call_alloc(void)
    115117{
    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 
    128122        _ipc_call_init(call);
    129         kobject_initialize(kobj, KOBJECT_TYPE_CALL, call);
    130         call->kobject = kobj;
    131123
    132124        return call;
     
    181173        if (!connected) {
    182174                /* We still have phone->kobject's reference; drop it */
    183                 kobject_put(phone->kobject);
     175                kobject_put(&phone->kobject);
    184176        }
    185177
     
    201193        atomic_store(&phone->active_calls, 0);
    202194        phone->label = 0;
    203         phone->kobject = NULL;
     195        kobject_initialize(&phone->kobject, KOBJECT_TYPE_PHONE);
    204196}
    205197
     
    294286                /* This is a forgotten call and call->sender is not valid. */
    295287                spinlock_unlock(&call->forget_lock);
    296                 kobject_put(call->kobject);
     288                kobject_put(&call->kobject);
    297289                return;
    298290        } else {
     
    352344
    353345        call->caller_phone = phone;
    354         kobject_add_ref(phone->kobject);
     346        kobject_add_ref(&phone->kobject);
    355347
    356348        if (preforget) {
     
    362354                else
    363355                        atomic_inc(&caller->answerbox.active_calls);
    364                 kobject_add_ref(phone->kobject);
     356                kobject_add_ref(&phone->kobject);
    365357                call->sender = caller;
    366358                call->active = true;
     
    479471
    480472                /* Drop the answerbox reference */
    481                 kobject_put(phone->kobject);
     473                kobject_put(&phone->kobject);
    482474
    483475                call_t *call = phone->hangup_call;
     
    581573                atomic_dec(&request->caller_phone->active_calls);
    582574                atomic_dec(&box->active_calls);
    583                 kobject_put(request->caller_phone->kobject);
     575                kobject_put(&request->caller_phone->kobject);
    584576        } else if (!list_empty(&box->calls)) {
    585577                /* Count received call */
     
    697689                        task_release(phone->caller);
    698690
    699                         kobject_put(phone->kobject);
     691                        kobject_put(&phone->kobject);
    700692
    701693                        /* Must start again */
     
    704696
    705697                mutex_unlock(&phone->lock);
    706                 kobject_put(phone->kobject);
     698                kobject_put(&phone->kobject);
    707699        }
    708700
     
    728720         * must hold a reference to it.
    729721         */
    730         kobject_add_ref(call->kobject);
     722        kobject_add_ref(&call->kobject);
    731723
    732724        spinlock_unlock(&call->forget_lock);
     
    735727        atomic_dec(&call->caller_phone->active_calls);
    736728        atomic_dec(&TASK->answerbox.active_calls);
    737         kobject_put(call->caller_phone->kobject);
     729        kobject_put(&call->caller_phone->kobject);
    738730
    739731        SYSIPC_OP(request_forget, call);
    740732
    741         kobject_put(call->kobject);
     733        kobject_put(&call->kobject);
    742734}
    743735
     
    777769static bool phone_cap_cleanup_cb(cap_t *cap, void *arg)
    778770{
    779         ipc_phone_hangup(cap->kobject->phone);
     771        ipc_phone_hangup(phone_from_kobject(cap->kobject));
    780772        kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
    781773            KOBJECT_TYPE_PHONE);
     
    798790                SYSIPC_OP(answer_process, call);
    799791
    800                 kobject_put(call->kobject);
     792                kobject_put(&call->kobject);
    801793
    802794                /*
     
    892884        answerbox_cache = slab_cache_create("answerbox_t", sizeof(answerbox_t),
    893885            0, NULL, NULL, 0);
     886        irq_cache = slab_cache_create("irq_t", sizeof(irq_kobject_t),
     887            0, NULL, NULL, 0);
    894888}
    895889
     
    927921static bool print_task_phone_cb(cap_t *cap, void *arg)
    928922{
    929         phone_t *phone = cap->kobject->phone;
     923        phone_t *phone = phone_from_kobject(cap->kobject);
    930924
    931925        mutex_lock(&phone->lock);
  • kernel/generic/src/ipc/ipcrsc.c

    re0e2264 r6caf5fb  
    4444#include <stdlib.h>
    4545
    46 static void phone_destroy(void *arg)
     46static void phone_destroy(kobject_t *arg)
    4747{
    48         phone_t *phone = (phone_t *) arg;
     48        phone_t *phone = phone_from_kobject(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                 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                 }
     78
    8479                call_t *hcall = ipc_call_alloc();
    8580                if (!hcall) {
    8681                        cap_free(TASK, handle);
    8782                        slab_free(phone_cache, phone);
    88                         free(kobj);
    8983                        return ENOMEM;
    9084                }
     
    9488                phone->hangup_call = hcall;
    9589
    96                 kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone);
    97                 phone->kobject = kobj;
    98 
    9990                if (publish)
    100                         cap_publish(task, handle, kobj);
     91                        cap_publish(task, handle, &phone->kobject);
    10192
    10293                *phandle = handle;
    10394                if (kobject)
    104                         *kobject = kobj;
     95                        *kobject = &phone->kobject;
    10596        }
    10697        return rc;
  • kernel/generic/src/ipc/irq.c

    re0e2264 r6caf5fb  
    295295}
    296296
    297 static void irq_destroy(void *arg)
    298 {
    299         irq_t *irq = (irq_t *) arg;
    300 
    301         irq_hash_out(irq);
     297static void irq_destroy(kobject_t *arg)
     298{
     299        irq_kobject_t *kobj = (irq_kobject_t *) arg;
     300
     301        irq_hash_out(&kobj->irq);
    302302
    303303        /* Free up the IRQ code and associated structures. */
    304         code_free(irq->notif_cfg.code);
    305         slab_free(irq_cache, irq);
     304        code_free(kobj->irq.notif_cfg.code);
     305        slab_free(irq_cache, kobj);
    306306}
    307307
     
    350350        }
    351351
    352         irq_t *irq = (irq_t *) slab_alloc(irq_cache, FRAME_ATOMIC);
    353         if (!irq) {
     352        irq_kobject_t *kobj = slab_alloc(irq_cache, FRAME_ATOMIC);
     353        if (!kobj) {
    354354                cap_free(TASK, handle);
    355355                return ENOMEM;
    356356        }
    357357
    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         }
     358        kobject_initialize(&kobj->kobject, KOBJECT_TYPE_IRQ);
     359
     360        irq_t *irq = &kobj->irq;
    364361
    365362        irq_initialize(irq);
     
    385382        irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    386383
    387         kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq);
    388         cap_publish(TASK, handle, kobject);
     384        cap_publish(TASK, handle, &kobj->kobject);
    389385
    390386        return EOK;
     
    405401                return ENOENT;
    406402
    407         assert(kobj->irq->notif_cfg.answerbox == box);
    408 
    409         irq_hash_out(kobj->irq);
     403        assert(irq_from_kobject(kobj)->notif_cfg.answerbox == box);
     404
     405        irq_hash_out(irq_from_kobject(kobj));
    410406
    411407        kobject_put(kobj);
  • kernel/generic/src/ipc/kbox.c

    re0e2264 r6caf5fb  
    242242        }
    243243
    244         kobject_t *phone_obj = kobject_get(TASK, phone_handle,
    245             KOBJECT_TYPE_PHONE);
     244        phone_t *phone = phone_from_kobject(
     245            kobject_get(TASK, phone_handle, 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_obj->phone, &task->kb.box);
     248        (void) ipc_phone_connect(phone, &task->kb.box);
    249249
    250250        mutex_unlock(&task->kb.cleanup_lock);
  • kernel/generic/src/ipc/ops/conctmeto.c

    re0e2264 r6caf5fb  
    8888
    8989        /* Set the recipient-assigned label */
    90         pobj->phone->label = ipc_get_arg5(&answer->data);
     90        phone_from_kobject(pobj)->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(pobj->phone, &TASK->answerbox);
     98                (void) ipc_phone_connect(phone_from_kobject(pobj), &TASK->answerbox);
    9999        } else {
    100100                /* Drop the extra reference */
  • kernel/generic/src/ipc/ops/concttome.c

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

    re0e2264 r6caf5fb  
    4545        task_t *other_task_s;
    4646
    47         kobject_t *sender_obj = kobject_get(TASK,
    48             (cap_handle_t) ipc_get_arg5(&call->data), KOBJECT_TYPE_PHONE);
    49         if (!sender_obj)
     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)
    5050                return ENOENT;
    5151
    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);
     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);
    5656                return EINVAL;
    5757        }
    5858
    59         other_task_s = sender_obj->phone->callee->task;
     59        other_task_s = sender_phone->callee->task;
    6060
    61         mutex_unlock(&sender_obj->phone->lock);
     61        mutex_unlock(&sender_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_obj);
     66        kobject_put(&sender_phone->kobject);
    6767        return EOK;
    6868}
     
    7777                task_t *other_task_r;
    7878
    79                 kobject_t *recipient_obj = kobject_get(TASK,
     79                phone_t *recipient_phone = phone_from_kobject(kobject_get(TASK,
    8080                    (cap_handle_t) ipc_get_arg1(&answer->data),
    81                     KOBJECT_TYPE_PHONE);
    82                 if (!recipient_obj) {
     81                    KOBJECT_TYPE_PHONE));
     82                if (!recipient_phone) {
    8383                        ipc_set_retval(&answer->data, ENOENT);
    8484                        return ENOENT;
    8585                }
    8686
    87                 mutex_lock(&recipient_obj->phone->lock);
    88                 if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
    89                         mutex_unlock(&recipient_obj->phone->lock);
     87                mutex_lock(&recipient_phone->lock);
     88                if (recipient_phone->state != IPC_PHONE_CONNECTED) {
     89                        mutex_unlock(&recipient_phone->lock);
    9090                        ipc_set_retval(&answer->data, EINVAL);
    91                         kobject_put(recipient_obj);
     91                        kobject_put(&recipient_phone->kobject);
    9292                        return EINVAL;
    9393                }
    9494
    95                 other_task_r = recipient_obj->phone->callee->task;
     95                other_task_r = recipient_phone->callee->task;
    9696                other_task_s = (task_t *) ipc_get_arg5(olddata);
    9797
     
    114114                }
    115115
    116                 mutex_unlock(&recipient_obj->phone->lock);
    117                 kobject_put(recipient_obj);
     116                mutex_unlock(&recipient_phone->lock);
     117                kobject_put(&recipient_phone->kobject);
    118118        }
    119119
  • kernel/generic/src/ipc/sysipc.c

    re0e2264 r6caf5fb  
    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         kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
    276         if (!kobj->phone)
     275        phone_t *phone = phone_from_kobject(
     276            kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
     277        if (!phone)
    277278                return ENOENT;
    278279
    279280        call_t *call = ipc_call_alloc();
    280281        if (!call) {
    281                 kobject_put(kobj);
     282                kobject_put(&phone->kobject);
    282283                return ENOMEM;
    283284        }
     
    286287        memcpy(call->data.args, data->args, sizeof(data->args));
    287288
    288         errno_t rc = request_preprocess(call, kobj->phone);
     289        errno_t rc = request_preprocess(call, phone);
    289290        if (!rc) {
    290291#ifdef CONFIG_UDEBUG
     
    292293#endif
    293294
    294                 kobject_add_ref(call->kobject);
    295                 rc = ipc_call_sync(kobj->phone, call);
     295                kobject_add_ref(&call->kobject);
     296                rc = ipc_call_sync(phone, call);
    296297                spinlock_lock(&call->forget_lock);
    297298                bool forgotten = call->forget;
    298299                spinlock_unlock(&call->forget_lock);
    299                 kobject_put(call->kobject);
     300                kobject_put(&call->kobject);
    300301
    301302#ifdef CONFIG_UDEBUG
     
    312313                                 * deallocation.
    313314                                 */
    314                                 kobject_put(call->kobject);
     315                                kobject_put(&call->kobject);
    315316                        } else {
    316317                                /*
     
    320321                                assert(rc == EINTR);
    321322                        }
    322                         kobject_put(kobj);
     323                        kobject_put(&phone->kobject);
    323324                        return rc;
    324325                }
     
    329330
    330331        memcpy(data->args, call->data.args, sizeof(data->args));
    331         kobject_put(call->kobject);
    332         kobject_put(kobj);
     332        kobject_put(&call->kobject);
     333        kobject_put(&phone->kobject);
    333334
    334335        return EOK;
     
    370371    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t label)
    371372{
    372         kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
    373         if (!kobj)
     373        phone_t *phone = phone_from_kobject(
     374            kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
     375
     376        if (!phone)
    374377                return ENOENT;
    375378
    376         if (check_call_limit(kobj->phone)) {
    377                 kobject_put(kobj);
     379        if (check_call_limit(phone)) {
     380                kobject_put(&phone->kobject);
    378381                return ELIMIT;
    379382        }
     
    381384        call_t *call = ipc_call_alloc();
    382385        if (!call) {
    383                 kobject_put(kobj);
     386                kobject_put(&phone->kobject);
    384387                return ENOMEM;
    385388        }
     
    399402        call->data.answer_label = label;
    400403
    401         errno_t res = request_preprocess(call, kobj->phone);
     404        errno_t res = request_preprocess(call, phone);
    402405
    403406        if (!res)
    404                 ipc_call(kobj->phone, call);
     407                ipc_call(phone, call);
    405408        else
    406                 ipc_backsend_err(kobj->phone, call, res);
    407 
    408         kobject_put(kobj);
     409                ipc_backsend_err(phone, call, res);
     410
     411        kobject_put(&phone->kobject);
    409412        return EOK;
    410413}
     
    422425    sysarg_t label)
    423426{
    424         kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
    425         if (!kobj)
     427        phone_t *phone = phone_from_kobject(
     428            kobject_get(TASK, handle, KOBJECT_TYPE_PHONE));
     429        if (!phone)
    426430                return ENOENT;
    427431
    428         if (check_call_limit(kobj->phone)) {
    429                 kobject_put(kobj);
     432        if (check_call_limit(phone)) {
     433                kobject_put(&phone->kobject);
    430434                return ELIMIT;
    431435        }
     
    433437        call_t *call = ipc_call_alloc();
    434438        if (!call) {
    435                 kobject_put(kobj);
     439                kobject_put(&phone->kobject);
    436440                return ENOMEM;
    437441        }
     
    440444            sizeof(call->data.args));
    441445        if (rc != EOK) {
    442                 kobject_put(call->kobject);
    443                 kobject_put(kobj);
     446                kobject_put(&call->kobject);
     447                kobject_put(&phone->kobject);
    444448                return (sys_errno_t) rc;
    445449        }
     
    448452        call->data.answer_label = label;
    449453
    450         errno_t res = request_preprocess(call, kobj->phone);
     454        errno_t res = request_preprocess(call, phone);
    451455
    452456        if (!res)
    453                 ipc_call(kobj->phone, call);
     457                ipc_call(phone, call);
    454458        else
    455                 ipc_backsend_err(kobj->phone, call, res);
    456 
    457         kobject_put(kobj);
     459                ipc_backsend_err(phone, call, res);
     460
     461        kobject_put(&phone->kobject);
    458462        return EOK;
    459463}
     
    489493                return ENOENT;
    490494
    491         call_t *call = ckobj->call;
     495        call_t *call = call_from_kobject(ckobj);
    492496
    493497        ipc_data_t old;
     
    551555        }
    552556
    553         rc = ipc_forward(call, pkobj->phone, &TASK->answerbox, mode);
     557        rc = ipc_forward(call, phone_from_kobject(pkobj), &TASK->answerbox, mode);
    554558        if (rc != EOK) {
    555559                after_forward = true;
     
    659663                return ENOENT;
    660664
    661         call_t *call = kobj->call;
     665        call_t *call = call_from_kobject(kobj);
    662666        assert(!(call->flags & IPC_CALL_ANSWERED));
    663667
     
    706710                return ENOENT;
    707711
    708         call_t *call = kobj->call;
     712        call_t *call = call_from_kobject(kobj);
    709713        assert(!(call->flags & IPC_CALL_ANSWERED));
    710714
     
    751755                return ENOENT;
    752756
    753         errno_t rc = ipc_phone_hangup(kobj->phone);
     757        errno_t rc = ipc_phone_hangup(phone_from_kobject(kobj));
    754758        kobject_put(kobj);
    755759        cap_free(TASK, handle);
     
    797801
    798802                STRUCT_TO_USPACE(calldata, &call->data);
    799                 kobject_put(call->kobject);
     803                kobject_put(&call->kobject);
    800804
    801805                return EOK;
     
    806810
    807811                if (call->flags & IPC_CALL_DISCARD_ANSWER) {
    808                         kobject_put(call->kobject);
     812                        kobject_put(&call->kobject);
    809813                        goto restart;
    810814                }
     
    813817
    814818                STRUCT_TO_USPACE(calldata, &call->data);
    815                 kobject_put(call->kobject);
     819                kobject_put(&call->kobject);
    816820
    817821                return EOK;
     
    836840                goto error;
    837841
    838         kobject_add_ref(call->kobject);
    839         cap_publish(TASK, handle, call->kobject);
     842        kobject_add_ref(&call->kobject);
     843        cap_publish(TASK, handle, &call->kobject);
    840844        return EOK;
    841845
  • kernel/generic/src/proc/task.c

    re0e2264 r6caf5fb  
    201201                return NULL;
    202202
     203        if (caps_task_init(task) != EOK) {
     204                slab_free(task_cache, task);
     205                return NULL;
     206        }
     207
    203208        refcount_init(&task->refcount);
    204209
     
    212217        task->ucycles = 0;
    213218        task->kcycles = 0;
    214 
    215         caps_task_init(task);
    216219
    217220        task->ipc_info.call_sent = 0;
     
    248251                }
    249252
    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);
     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);
    253256        }
    254257
     
    287290         */
    288291        as_release(task->as);
     292
     293        caps_task_clear(task);
    289294
    290295        slab_free(task_cache, task);
  • kernel/generic/src/proc/thread.c

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

    re0e2264 r6caf5fb  
    4848static slab_cache_t *waitq_cache;
    4949
    50 static void waitq_destroy(void *arg)
     50typedef struct {
     51        kobject_t kobject;
     52        waitq_t waitq;
     53} waitq_kobject_t;
     54
     55static void waitq_destroy(kobject_t *arg)
    5156{
    52         waitq_t *wq = (waitq_t *) arg;
     57        waitq_kobject_t *wq = (waitq_kobject_t *) arg;
    5358        slab_free(waitq_cache, wq);
    5459}
    5560
    5661kobject_ops_t waitq_kobject_ops = {
    57         .destroy = waitq_destroy
     62        .destroy = waitq_destroy,
    5863};
    59 
    60 static 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 }
    6864
    6965/** Initialize the user waitq subsystem */
    7066void sys_waitq_init(void)
    7167{
    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 */
    77 void sys_waitq_task_cleanup(void)
    78 {
    79         caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_WAITQ,
    80             waitq_cap_cleanup_cb, NULL);
     68        waitq_cache = slab_cache_create("syswaitq_t", sizeof(waitq_kobject_t),
     69            0, NULL, NULL, 0);
    8170}
    8271
     
    9079sys_errno_t sys_waitq_create(uspace_ptr_cap_waitq_handle_t whandle)
    9180{
    92         waitq_t *wq = slab_alloc(waitq_cache, FRAME_ATOMIC);
    93         if (!wq)
     81        waitq_kobject_t *kobj = slab_alloc(waitq_cache, FRAME_ATOMIC);
     82        if (!kobj)
    9483                return (sys_errno_t) ENOMEM;
    95         waitq_initialize(wq);
    9684
    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);
     85        kobject_initialize(&kobj->kobject, KOBJECT_TYPE_WAITQ);
     86        waitq_initialize(&kobj->waitq);
    10387
    10488        cap_handle_t handle;
    10589        errno_t rc = cap_alloc(TASK, &handle);
    10690        if (rc != EOK) {
    107                 slab_free(waitq_cache, wq);
    108                 kobject_free(kobj);
     91                slab_free(waitq_cache, kobj);
    10992                return (sys_errno_t) rc;
    11093        }
     
    11396        if (rc != EOK) {
    11497                cap_free(TASK, handle);
    115                 kobject_free(kobj);
    116                 slab_free(waitq_cache, wq);
     98                slab_free(waitq_cache, kobj);
    11799                return (sys_errno_t) rc;
    118100        }
    119101
    120         cap_publish(TASK, handle, kobj);
     102        cap_publish(TASK, handle, &kobj->kobject);
    121103
    122104        return (sys_errno_t) EOK;
     
    151133    unsigned int flags)
    152134{
    153         kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
     135        waitq_kobject_t *kobj =
     136            (waitq_kobject_t *) kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
    154137        if (!kobj)
    155138                return (sys_errno_t) ENOENT;
     
    159142#endif
    160143
    161         errno_t rc = _waitq_sleep_timeout(kobj->waitq, timeout,
     144        errno_t rc = _waitq_sleep_timeout(&kobj->waitq, timeout,
    162145            SYNCH_FLAGS_INTERRUPTIBLE | flags);
    163146
     
    166149#endif
    167150
    168         kobject_put(kobj);
     151        kobject_put(&kobj->kobject);
    169152
    170153        return (sys_errno_t) rc;
     
    179162sys_errno_t sys_waitq_wakeup(cap_waitq_handle_t whandle)
    180163{
    181         kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
     164        waitq_kobject_t *kobj =
     165            (waitq_kobject_t *) kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
    182166        if (!kobj)
    183167                return (sys_errno_t) ENOENT;
    184168
    185         waitq_wake_one(kobj->waitq);
     169        waitq_wake_one(&kobj->waitq);
    186170
    187         kobject_put(kobj);
     171        kobject_put(&kobj->kobject);
    188172        return (sys_errno_t) EOK;
    189173}
  • kernel/generic/src/sysinfo/stats.c

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