Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/src/pthread/keys.c

    r9b8be79 r98743e2  
    3636#include <pthread.h>
    3737#include <errno.h>
     38#include <fibril.h>
     39#include <stdatomic.h>
    3840#include "../internal/common.h"
     41
     42#include <stdio.h>
     43#define DPRINTF(format, ...) ((void) 0);
     44
     45static fibril_local bool fibril_initialized = false;
     46static atomic_ushort next_key = 1; // skip the key 'zero'
     47
     48/*
     49 * For now, we just support maximum of 100 keys. This can be improved
     50 * in the future by implementing a dynamically growing array with
     51 * reallocations, but that will require more synchronization.
     52 */
     53#define PTHREAD_KEYS_MAX 100
     54
     55static fibril_local void *key_data[PTHREAD_KEYS_MAX];
    3956
    4057void *pthread_getspecific(pthread_key_t key)
    4158{
    42         not_implemented();
    43         return NULL;
     59        // initialization is done in setspecific -> if not initialized, nothing was set yet
     60        if (!fibril_initialized) {
     61                DPRINTF("pthread_getspecific(%d) = NULL (uninitialized)\n", key);
     62                return NULL;
     63        }
     64
     65        assert(key < PTHREAD_KEYS_MAX);
     66        assert(key < next_key);
     67        assert(key > 0);
     68
     69        DPRINTF("pthread_getspecific(%d) = %p\n", key, key_data[key]);
     70        return key_data[key];
    4471}
    4572
    4673int pthread_setspecific(pthread_key_t key, const void *data)
    4774{
    48         not_implemented();
    49         return ENOTSUP;
     75        DPRINTF("pthread_setspecific(%d, %p)\n", key, data);
     76        if (!fibril_initialized) {
     77                DPRINTF("initializing pthread keys\n");
     78                for (unsigned i = 0; i < PTHREAD_KEYS_MAX; i++) {
     79                        key_data[i] = NULL;
     80                }
     81                fibril_initialized = true;
     82        }
     83        assert(key < PTHREAD_KEYS_MAX);
     84        assert(key < next_key);
     85        assert(key > 0);
     86
     87        key_data[key] = (void *) data;
     88        return EOK;
    5089}
    5190
    5291int pthread_key_delete(pthread_key_t key)
    5392{
     93        // see https://github.com/HelenOS/helenos/pull/245#issuecomment-2706795848
    5494        not_implemented();
    55         return ENOTSUP;
     95        return EOK;
    5696}
    5797
    5898int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
    5999{
    60         not_implemented();
    61         return ENOTSUP;
     100        unsigned short k = atomic_fetch_add(&next_key, 1);
     101        DPRINTF("pthread_key_create(%p, %p) = %d\n", key, destructor, k);
     102        if (k >= PTHREAD_KEYS_MAX) {
     103                atomic_store(&next_key, PTHREAD_KEYS_MAX + 1);
     104                return ELIMIT;
     105        }
     106        if (destructor != NULL) {
     107                static int __counter = 0;
     108                if (__counter == 0) {
     109                        fprintf(stderr, "pthread_key_create: destructors not supported\n");
     110                }
     111                __counter++;
     112        }
     113
     114        *key = k;
     115        return EOK;
    62116}
    63117
Note: See TracChangeset for help on using the changeset viewer.