Changeset d54b303 in mainline


Ignore:
Timestamp:
2012-12-04T05:18:19Z (11 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32d2e60
Parents:
9a3b469
Message:

Initial version of nop futexes that are upgradable to proper futexes.

Location:
uspace/lib/c
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r9a3b469 rd54b303  
    5252SLIBRARY = libc.so.0.0
    5353LSONAME = libc.so0
     54
     55LIBS = $(LIBURCU_PREFIX)/liburcu.a
     56EXTRA_CFLAGS += -I$(LIBURCU_PREFIX)
    5457
    5558
  • uspace/lib/c/generic/fibril.c

    r9a3b469 rd54b303  
    5151#include <futex.h>
    5252
     53#ifdef FUTEX_UPGRADABLE
     54#include <rcu.h>
     55#endif
     56
    5357/**
    5458 * This futex serializes access to ready_list,
     
    8387{
    8488        fibril_t *fibril = __tcb_get()->fibril_data;
     89
     90#ifdef FUTEX_UPGRADABLE
     91        rcu_register_fibril();
     92#endif
    8593       
    8694        /* Call the implementing function. */
     
    245253       
    246254        futex_up(&fibril_futex);
     255       
     256#ifdef FUTEX_UPGRADABLE
     257        if (stype == FIBRIL_FROM_DEAD) {
     258                rcu_deregister_fibril();
     259        }
     260#endif
     261       
    247262        context_restore(&dstf->ctx);
    248263        /* not reached */
  • uspace/lib/c/generic/futex.c

    r9a3b469 rd54b303  
    4848
    4949
     50#ifdef FUTEX_UPGRADABLE
     51
     52int _upgrade_futex = 0;
     53static futex_t upg_and_wait_futex = FUTEX_INITIALIZER;
     54
     55void futex_upgrade_all_and_wait(void)
     56{
     57        _futex_down(&upg_and_wait_futex);
     58       
     59        if (!_upgrade_futex) {
     60                rcu_assign(_upgrade_futex, 1);
     61                rcu_synchronize();
     62        }
     63       
     64        _futex_up(&upg_and_wait_futex);
     65}
     66
     67#endif
     68
    5069/** @}
    5170 */
  • uspace/lib/c/generic/libc.c

    r9a3b469 rd54b303  
    5151#include "private/malloc.h"
    5252#include "private/io.h"
    53 #include "private/thread.h"
     53
     54#ifdef FUTEX_UPGRADABLE
     55#include <rcu.h>
     56#endif
    5457
    5558#ifdef CONFIG_RTLD
    5659#include <rtld/rtld.h>
    5760#endif
     61
    5862
    5963static bool env_setup = false;
     
    6367        /* Initialize user task run-time environment */
    6468        __malloc_init();
    65         __async_init();
    6669       
    6770        fibril_t *fibril = fibril_setup();
     
    7477        __pcb = (pcb_t *) pcb_ptr;
    7578       
    76         atomic_inc(&_created_thread_cnt);
     79#ifdef FUTEX_UPGRADABLE
     80        rcu_register_fibril();
     81#endif
     82       
     83        __async_init();
    7784       
    7885        /* The basic run-time environment is setup */
  • uspace/lib/c/generic/malloc.c

    r9a3b469 rd54b303  
    4747#include <adt/gcdlcm.h>
    4848#include "private/malloc.h"
    49 #include "private/thread.h"
    5049
    5150/** Magic used in heap headers. */
     
    201200        do { \
    202201                if (!(expr)) {\
    203                         futex_up(&malloc_futex); \
     202                        _futex_up(&malloc_futex); \
    204203                        assert_abort(#expr, __FILE__, __LINE__); \
    205204                } \
     
    786785void *malloc(const size_t size)
    787786{
    788         /* Do not use futexes for allocations during main thread initialization. */
    789         if (0 == atomic_get(&_created_thread_cnt)) {
    790                 return malloc_internal(size, BASE_ALIGN);
    791         } else {
    792                 futex_down(&malloc_futex);
    793                 void *block = malloc_internal(size, BASE_ALIGN);
    794                 futex_up(&malloc_futex);
    795                 return block;
    796         }
     787        _futex_down(&malloc_futex);
     788        void *block = malloc_internal(size, BASE_ALIGN);
     789        _futex_up(&malloc_futex);
     790
     791        return block;
    797792}
    798793
     
    813808            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    814809
    815         /* Do not use futexes for allocations during main thread initialization. */
    816         if (0 == atomic_get(&_created_thread_cnt)) {
    817                 return malloc_internal(size, palign);
    818         } else {
    819                 futex_down(&malloc_futex);
    820                 void *block = malloc_internal(size, palign);
    821                 futex_up(&malloc_futex);
    822 
    823                 return block;
    824         }
     810        _futex_down(&malloc_futex);
     811        void *block = malloc_internal(size, palign);
     812        _futex_up(&malloc_futex);
     813
     814        return block;
    825815}
    826816
     
    838828                return malloc(size);
    839829       
    840         futex_down(&malloc_futex);
     830        _futex_down(&malloc_futex);
    841831       
    842832        /* Calculate the position of the header. */
     
    895885        }
    896886       
    897         futex_up(&malloc_futex);
     887        _futex_up(&malloc_futex);
    898888       
    899889        if (reloc) {
     
    918908                return;
    919909       
    920         futex_down(&malloc_futex);
     910        _futex_down(&malloc_futex);
    921911       
    922912        /* Calculate the position of the header. */
     
    963953        heap_shrink(area);
    964954       
    965         futex_up(&malloc_futex);
     955        _futex_up(&malloc_futex);
    966956}
    967957
    968958void *heap_check(void)
    969959{
    970         futex_down(&malloc_futex);
     960        _futex_down(&malloc_futex);
    971961       
    972962        if (first_heap_area == NULL) {
    973                 futex_up(&malloc_futex);
     963                _futex_up(&malloc_futex);
    974964                return (void *) -1;
    975965        }
     
    985975                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
    986976                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
    987                         futex_up(&malloc_futex);
     977                        _futex_up(&malloc_futex);
    988978                        return (void *) area;
    989979                }
     
    996986                        /* Check heap block consistency */
    997987                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
    998                                 futex_up(&malloc_futex);
     988                                _futex_up(&malloc_futex);
    999989                                return (void *) head;
    1000990                        }
     
    1004994                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
    1005995                            (head->size != foot->size)) {
    1006                                 futex_up(&malloc_futex);
     996                                _futex_up(&malloc_futex);
    1007997                                return (void *) foot;
    1008998                        }
     
    10101000        }
    10111001       
    1012         futex_up(&malloc_futex);
     1002        _futex_up(&malloc_futex);
    10131003       
    10141004        return NULL;
  • uspace/lib/c/generic/private/thread.h

    r9a3b469 rd54b303  
    4141extern void __thread_main(uspace_arg_t *);
    4242
    43 struct atomic;
    44 extern struct atomic _created_thread_cnt;
    45 
    4643#endif
    4744
  • uspace/lib/c/generic/thread.c

    r9a3b469 rd54b303  
    4646#include "private/thread.h"
    4747
    48 /**
    49  * The number of threads that have been created and initialized since
    50  * the start of the program.
    51  */
    52 atomic_t _created_thread_cnt = {0};
     48#ifdef FUTEX_UPGRADABLE
     49#include <rcu.h>
     50#endif
     51
    5352
    5453/** Main thread function.
     
    6968        __tcb_set(fibril->tcb);
    7069       
    71         atomic_inc(&_created_thread_cnt);
     70#ifdef FUTEX_UPGRADABLE
     71        rcu_register_fibril();
     72        futex_upgrade_all_and_wait();
     73#endif
    7274       
    7375        uarg->uspace_thread_function(uarg->uspace_thread_arg);
     
    8183        /* If there is a manager, destroy it */
    8284        async_destroy_manager();
     85
     86#ifdef FUTEX_UPGRADABLE
     87        rcu_deregister_fibril();
     88#endif
     89       
    8390        fibril_teardown(fibril);
    8491       
  • uspace/lib/c/include/futex.h

    r9a3b469 rd54b303  
    4040#include <libc.h>
    4141
    42 #define FUTEX_INITIALIZE(val) {{(val)}}
    43 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    44 
    4542typedef struct futex {
    4643        atomic_t val;
     44#ifdef FUTEX_UPGRADABLE
     45        int upgraded;
     46#endif
    4747} futex_t;
    4848
     
    5050extern void futex_initialize(futex_t *futex, int value);
    5151
     52#ifdef FUTEX_UPGRADABLE
     53#include <rcu.h>
     54
     55#define FUTEX_INITIALIZE(val) {{(val)}, {0}}
     56
     57#define futex_down(fut) \
     58({ \
     59        rcu_read_lock(); \
     60        (fut)->upgraded = rcu_access(_upgrade_futexes); \
     61        if ((fut)->upgraded) \
     62                (void) _futex_down((fut)); \
     63})
     64
     65#define futex_trydown(fut) \
     66({ \
     67        rcu_read_lock(); \
     68        int _upgraded = rcu_access(_upgrade_futexes); \
     69        if (_upgraded) { \
     70                int _acquired = _futex_trydown((fut)); \
     71                if (!_acquired) { \
     72                        rcu_read_unlock(); \
     73                } else { \
     74                        (fut)->upgraded = true; \
     75                } \
     76                _acquired; \
     77        } else { \
     78                (fut)->upgraded = false; \
     79                1; \
     80        } \
     81})
     82               
     83#define futex_up(fut) \
     84({ \
     85        if ((fut)->upgraded) \
     86                (void) _futex_up((fut)); \
     87        rcu_read_unlock(); \
     88})
     89
     90extern int _upgrade_futexes;
     91
     92extern void futex_upgrade_all_and_wait(void);
     93               
     94#else
     95
     96#define FUTEX_INITIALIZE(val) {{(val)}}
     97
    5298#define futex_down(fut)     (void)_futex_down((fut))
    5399#define futex_trydown(fut)  _futex_trydown((fut))
    54100#define futex_up(fut)       (void)_futex_up((fut))
     101               
     102#endif
    55103
     104#define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    56105
    57106/** Try to down the futex.
Note: See TracChangeset for help on using the changeset viewer.