Changeset 40abf56 in mainline for uspace/lib/c/generic/fibril.c


Ignore:
Timestamp:
2018-07-18T19:42:28Z (6 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9bde0d5
Parents:
0b05082
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-18 19:05:08)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-18 19:42:28)
Message:

Make sure that a thread with uninitialized TLS does not need to call malloc()
to initialize it.

For threads and tasks created by loader, we create TLS beforehand and pass
it to the child. For tasks spawned directly by the kernel, we require it is
a static executable and allocate the initial TLS using as_area_create() instead
of the libc allocator.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril.c

    r0b05082 r40abf56  
    5050#include "private/thread.h"
    5151#include "private/fibril.h"
    52 
     52#include "private/libc.h"
    5353
    5454/**
     
    8585}
    8686
    87 /** Setup fibril information into TCB structure
    88  *
    89  */
    90 fibril_t *fibril_setup(void)
    91 {
    92         tcb_t *tcb = tls_make();
     87/** Allocate a fibril structure and TCB, but don't do anything else with it. */
     88fibril_t *fibril_alloc(void)
     89{
     90        tcb_t *tcb = tls_make(__progsymbols.elfstart);
    9391        if (!tcb)
    9492                return NULL;
     
    102100        tcb->fibril_data = fibril;
    103101        fibril->tcb = tcb;
    104 
    105         /*
    106          * We are called before __tcb_set(), so we need to use
    107          * futex_down/up() instead of futex_lock/unlock() that
    108          * may attempt to access TLS.
    109          */
    110         futex_down(&fibril_futex);
    111         list_append(&fibril->all_link, &fibril_list);
    112         futex_up(&fibril_futex);
    113 
     102        fibril->is_freeable = true;
     103
     104        fibril_setup(fibril);
    114105        return fibril;
     106}
     107
     108/**
     109 * Put the fibril into fibril_list.
     110 */
     111void fibril_setup(fibril_t *f)
     112{
     113        futex_lock(&fibril_futex);
     114        list_append(&f->all_link, &fibril_list);
     115        futex_unlock(&fibril_futex);
    115116}
    116117
     
    122123        if (!locked)
    123124                futex_unlock(&fibril_futex);
    124         tls_free(fibril->tcb);
    125         free(fibril);
     125
     126        if (fibril->is_freeable) {
     127                tls_free(fibril->tcb);
     128                free(fibril);
     129        }
    126130}
    127131
     
    239243        fibril_t *fibril;
    240244
    241         fibril = fibril_setup();
     245        fibril = fibril_alloc();
    242246        if (fibril == NULL)
    243247                return 0;
     
    248252            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
    249253            AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED);
    250         if (fibril->stack == (void *) -1) {
     254        if (fibril->stack == AS_MAP_FAILED) {
    251255                fibril_teardown(fibril, false);
    252256                return 0;
     
    324328fibril_t *fibril_self(void)
    325329{
    326         return __tcb_get()->fibril_data;
     330        assert(__tcb_is_set());
     331        tcb_t *tcb = __tcb_get();
     332        assert(tcb->fibril_data);
     333        return tcb->fibril_data;
    327334}
    328335
Note: See TracChangeset for help on using the changeset viewer.