Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 45c8eea in mainline


Ignore:
Timestamp:
2018-11-11T15:47:39Z (3 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
f4cb6c5f
Parents:
269bc459
git-author:
Jakub Jermar <jakub@…> (2018-11-10 17:49:44)
git-committer:
Jakub Jermar <jakub@…> (2018-11-11 15:47:39)
Message:

Preallocate waitq handle during initialization

Do not clutter futex_down_composable() with the preallocation of the
wait queue handle and do it single-threadedly in futex_initialize().

Location:
uspace/lib/c
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async/client.c

    r269bc459 r45c8eea  
    122122#include "../private/fibril.h"
    123123
    124 static FIBRIL_RMUTEX_INITIALIZE(message_mutex);
     124static fibril_rmutex_t message_mutex;
    125125
    126126/** Naming service session */
     
    173173void __async_client_init(void)
    174174{
     175        if (fibril_rmutex_initialize(&message_mutex) != EOK)
     176                abort();
     177
    175178        session_ns.iface = 0;
    176179        session_ns.mgmt = EXCHANGE_ATOMIC;
  • uspace/lib/c/generic/async/ports.c

    r269bc459 r45c8eea  
    100100
    101101/** Futex guarding the interface hash table. */
    102 static FIBRIL_RMUTEX_INITIALIZE(interface_mutex);
     102static fibril_rmutex_t interface_mutex;
    103103static hash_table_t interface_hash_table;
    104104
     
    292292void __async_ports_init(void)
    293293{
     294        if (fibril_rmutex_initialize(&interface_mutex) != EOK)
     295                abort();
     296
    294297        if (!hash_table_create(&interface_hash_table, 0, 0,
    295298            &interface_hash_table_ops))
  • uspace/lib/c/generic/async/server.c

    r269bc459 r45c8eea  
    216216}
    217217
    218 static FIBRIL_RMUTEX_INITIALIZE(client_mutex);
     218static fibril_rmutex_t client_mutex;
    219219static hash_table_t client_hash_table;
    220220
    221221// TODO: lockfree notification_queue?
    222 static FIBRIL_RMUTEX_INITIALIZE(notification_mutex);
     222static fibril_rmutex_t notification_mutex;
    223223static hash_table_t notification_hash_table;
    224224static LIST_INITIALIZE(notification_queue);
     
    10131013void __async_server_init(void)
    10141014{
     1015        if (fibril_rmutex_initialize(&client_mutex) != EOK)
     1016                abort();
     1017        if (fibril_rmutex_initialize(&notification_mutex) != EOK)
     1018                abort();
     1019
    10151020        if (!hash_table_create(&client_hash_table, 0, 0, &client_hash_table_ops))
    10161021                abort();
  • uspace/lib/c/generic/io/kio.c

    r269bc459 r45c8eea  
    3838#include <str.h>
    3939#include <stdint.h>
     40#include <stdlib.h>
    4041#include <errno.h>
    4142#include <abi/kio.h>
     
    5354        char data[KIO_BUFFER_SIZE];
    5455        size_t used;
    55 } kio_buffer = { .futex = FUTEX_INITIALIZER, };
     56} kio_buffer;
     57
     58void __kio_init(void)
     59{
     60        if (futex_initialize(&kio_buffer.futex, 1) != EOK)
     61                abort();
     62}
    5663
    5764errno_t kio_write(const void *buf, size_t size, size_t *nwritten)
  • uspace/lib/c/generic/libc.c

    r269bc459 r45c8eea  
    4040#include <tls.h>
    4141#include <fibril.h>
     42#include <fibril_synch.h>
    4243#include <task.h>
    4344#include <loader/pcb.h>
    4445#include <vfs/vfs.h>
    4546#include <vfs/inbox.h>
     47#include <io/kio.h>
    4648#include "private/libc.h"
    4749#include "private/async.h"
     
    6163void __libc_main(void *pcb_ptr)
    6264{
     65        __kio_init();
     66
    6367        assert(!__tcb_is_set());
    6468
     
    8185
    8286        __fibrils_init();
     87        __fibril_synch_init();
    8388
    8489        /* Initialize the fibril. */
  • uspace/lib/c/generic/malloc.c

    r269bc459 r45c8eea  
    195195
    196196/** Futex for thread-safe heap manipulation */
    197 static FIBRIL_RMUTEX_INITIALIZE(malloc_mutex);
     197static fibril_rmutex_t malloc_mutex;
    198198
    199199#define malloc_assert(expr) safe_assert(expr)
     
    484484void __malloc_init(void)
    485485{
     486        if (fibril_rmutex_initialize(&malloc_mutex) != EOK)
     487                abort();
     488
    486489        if (!area_create(PAGE_SIZE))
    487490                abort();
  • uspace/lib/c/generic/private/fibril.h

    r269bc459 r45c8eea  
    120120} fibril_rmutex_t;
    121121
    122 #define FIBRIL_RMUTEX_INITIALIZER(name) \
    123         { .futex = FUTEX_INITIALIZE(1) }
    124 
    125 #define FIBRIL_RMUTEX_INITIALIZE(name) \
    126         fibril_rmutex_t name = FIBRIL_RMUTEX_INITIALIZER(name)
    127 
    128 extern void fibril_rmutex_initialize(fibril_rmutex_t *);
     122extern errno_t fibril_rmutex_initialize(fibril_rmutex_t *);
    129123extern void fibril_rmutex_destroy(fibril_rmutex_t *);
    130124extern void fibril_rmutex_lock(fibril_rmutex_t *);
  • uspace/lib/c/generic/private/futex.h

    r269bc459 r45c8eea  
    4646typedef struct futex {
    4747        volatile atomic_int val;
    48         volatile atomic_int lock;
    4948        volatile cap_waitq_handle_t whandle;
    5049
     
    5453} futex_t;
    5554
    56 extern void futex_initialize(futex_t *futex, int value);
     55extern errno_t futex_initialize(futex_t *futex, int value);
    5756
    5857static inline errno_t futex_destroy(futex_t *futex)
     
    6463
    6564#ifdef CONFIG_DEBUG_FUTEX
    66 
    67 #define FUTEX_INITIALIZE(val) { (val), 0, CAP_NIL, NULL }
    68 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    6965
    7066void __futex_assert_is_locked(futex_t *, const char *);
     
    8581#else
    8682
    87 #define FUTEX_INITIALIZE(val) { (val), 0, CAP_NIL }
    88 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    89 
    9083#define futex_lock(fut)     (void) futex_down((fut))
    9184#define futex_trylock(fut)  futex_trydown((fut))
     
    9891#endif
    9992
    100 static errno_t allocate_waitq(futex_t *futex)
    101 {
    102         int expected = 0;
    103         while (!atomic_compare_exchange_weak_explicit(&futex->lock, &expected,
    104             1, memory_order_acquire, memory_order_relaxed))
    105                 expected = 0;
    106 
    107         if (futex->whandle == CAP_NIL) {
    108                 errno_t rc = __SYSCALL1(SYS_WAITQ_CREATE,
    109                     (sysarg_t) &futex->whandle);
    110                 if (rc != EOK) {
    111                         atomic_store_explicit(&futex->lock, 0,
    112                             memory_order_release);
    113                         return rc;
    114                 }
    115         }
    116 
    117         atomic_store_explicit(&futex->lock, 0, memory_order_release);
    118         return EOK;
     93static inline errno_t futex_allocate_waitq(futex_t *futex)
     94{
     95        return __SYSCALL1(SYS_WAITQ_CREATE, (sysarg_t) &futex->whandle);
    11996}
    12097
     
    140117        // TODO: Add tests for this.
    141118
    142         // Preallocate the waitq handle so that we don't need to risk a failure
    143         // during wakeup
    144         if (futex->whandle == CAP_NIL) {
    145                 errno_t rc = allocate_waitq(futex);
    146                 if (rc != EOK)
    147                         return rc;
    148         }
     119        assert(futex->whandle != CAP_NIL);
    149120
    150121        if (atomic_fetch_sub_explicit(&futex->val, 1, memory_order_acquire) > 0)
  • uspace/lib/c/generic/thread/fibril.c

    r269bc459 r45c8eea  
    8787
    8888/* This futex serializes access to global data. */
    89 static futex_t fibril_futex = FUTEX_INITIALIZER;
     89static futex_t fibril_futex;
    9090static futex_t ready_semaphore;
    9191static long ready_st_count;
     
    9595static LIST_INITIALIZE(timeout_list);
    9696
    97 static futex_t ipc_lists_futex = FUTEX_INITIALIZER;
     97static futex_t ipc_lists_futex;
    9898static LIST_INITIALIZE(ipc_waiter_list);
    9999static LIST_INITIALIZE(ipc_buffer_list);
     
    796796        if (!multithreaded) {
    797797                _ready_debug_check();
    798                 futex_initialize(&ready_semaphore, ready_st_count);
     798                if (futex_initialize(&ready_semaphore, ready_st_count) != EOK)
     799                        abort();
    799800                multithreaded = true;
    800801        }
     
    861862void __fibrils_init(void)
    862863{
     864        if (futex_initialize(&fibril_futex, 1) != EOK)
     865                abort();
     866        if (futex_initialize(&ipc_lists_futex, 1) != EOK)
     867                abort();
     868
    863869        /*
    864870         * We allow a fixed, small amount of parallelism for IPC reads, but
  • uspace/lib/c/generic/thread/fibril_synch.c

    r269bc459 r45c8eea  
    5151#include "../private/futex.h"
    5252
    53 void fibril_rmutex_initialize(fibril_rmutex_t *m)
    54 {
    55         futex_initialize(&m->futex, 1);
     53errno_t fibril_rmutex_initialize(fibril_rmutex_t *m)
     54{
     55        return futex_initialize(&m->futex, 1);
    5656}
    5757
     
    9090static fibril_local bool deadlocked = false;
    9191
    92 static futex_t fibril_synch_futex = FUTEX_INITIALIZER;
     92static futex_t fibril_synch_futex;
     93
     94void __fibril_synch_init(void)
     95{
     96        if (futex_initialize(&fibril_synch_futex, 1) != EOK)
     97                abort();
     98}
    9399
    94100typedef struct {
  • uspace/lib/c/generic/thread/futex.c

    r269bc459 r45c8eea  
    4949 * @param val   Initialization value.
    5050 *
     51 * @return      Error code.
    5152 */
    52 void futex_initialize(futex_t *futex, int val)
     53errno_t futex_initialize(futex_t *futex, int val)
    5354{
    5455        atomic_store_explicit(&futex->val, val, memory_order_relaxed);
    55         atomic_store_explicit(&futex->lock, 0, memory_order_relaxed);
    5656        futex->whandle = CAP_NIL;
     57        return futex_allocate_waitq(futex);
    5758}
    5859
  • uspace/lib/c/generic/thread/mpsc.c

    r269bc459 r45c8eea  
    8080        }
    8181
     82        if (fibril_rmutex_initialize(&q->t_lock) != EOK) {
     83                free(q);
     84                free(n);
     85                free(c);
     86                return NULL;
     87        }
     88
    8289        q->elem_size = elem_size;
    83         fibril_rmutex_initialize(&q->t_lock);
    8490        q->head = q->tail = n;
    8591        q->close_node = c;
  • uspace/lib/c/include/fibril_synch.h

    r269bc459 r45c8eea  
    164164        fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
    165165
     166extern void __fibril_synch_init(void);
     167
    166168extern void fibril_mutex_initialize(fibril_mutex_t *);
    167169extern void fibril_mutex_lock(fibril_mutex_t *);
  • uspace/lib/c/include/io/kio.h

    r269bc459 r45c8eea  
    4242#include <_bits/size_t.h>
    4343
     44extern void __kio_init(void);
    4445extern errno_t kio_write(const void *, size_t, size_t *);
    4546extern void kio_update(void);
Note: See TracChangeset for help on using the changeset viewer.