111 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2006-2021, RT-Thread Development Team
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: Apache-2.0
 | 
						|
 *
 | 
						|
 * Change Logs:
 | 
						|
 * Date           Author       Notes
 | 
						|
 * 2010-10-26     Bernard      the first version
 | 
						|
 */
 | 
						|
 | 
						|
#include <pthread.h>
 | 
						|
#include "pthread_internal.h"
 | 
						|
 | 
						|
_pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
 | 
						|
 | 
						|
/* initialize key area */
 | 
						|
static int pthread_key_system_init(void)
 | 
						|
{
 | 
						|
    rt_memset(&_thread_keys[0], 0, sizeof(_thread_keys));
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
INIT_COMPONENT_EXPORT(pthread_key_system_init);
 | 
						|
 | 
						|
void *pthread_getspecific(pthread_key_t key)
 | 
						|
{
 | 
						|
    struct _pthread_data* ptd;
 | 
						|
 | 
						|
    if (rt_thread_self() == NULL) return NULL;
 | 
						|
 | 
						|
    /* get pthread data from user data of thread */
 | 
						|
    ptd = (_pthread_data_t *)rt_thread_self()->user_data;
 | 
						|
    RT_ASSERT(ptd != NULL);
 | 
						|
 | 
						|
    if (ptd->tls == NULL)
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    if ((key < PTHREAD_KEY_MAX) && (_thread_keys[key].is_used))
 | 
						|
        return ptd->tls[key];
 | 
						|
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
RTM_EXPORT(pthread_getspecific);
 | 
						|
 | 
						|
int pthread_setspecific(pthread_key_t key, const void *value)
 | 
						|
{
 | 
						|
    struct _pthread_data* ptd;
 | 
						|
 | 
						|
    if (rt_thread_self() == NULL) return EINVAL;
 | 
						|
 | 
						|
    /* get pthread data from user data of thread */
 | 
						|
    ptd = (_pthread_data_t *)rt_thread_self()->user_data;
 | 
						|
    RT_ASSERT(ptd != NULL);
 | 
						|
 | 
						|
    /* check tls area */
 | 
						|
    if (ptd->tls == NULL)
 | 
						|
    {
 | 
						|
        ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX);
 | 
						|
    }
 | 
						|
 | 
						|
    if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used)
 | 
						|
    {
 | 
						|
        ptd->tls[key] = (void *)value;
 | 
						|
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return EINVAL;
 | 
						|
}
 | 
						|
RTM_EXPORT(pthread_setspecific);
 | 
						|
 | 
						|
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
 | 
						|
{
 | 
						|
    rt_uint32_t index;
 | 
						|
 | 
						|
    rt_enter_critical();
 | 
						|
    for (index = 0; index < PTHREAD_KEY_MAX; index ++)
 | 
						|
    {
 | 
						|
        if (_thread_keys[index].is_used == 0)
 | 
						|
        {
 | 
						|
            _thread_keys[index].is_used = 1;
 | 
						|
            _thread_keys[index].destructor = destructor;
 | 
						|
 | 
						|
            *key = index;
 | 
						|
 | 
						|
            rt_exit_critical();
 | 
						|
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    rt_exit_critical();
 | 
						|
 | 
						|
    return EAGAIN;
 | 
						|
}
 | 
						|
RTM_EXPORT(pthread_key_create);
 | 
						|
 | 
						|
int pthread_key_delete(pthread_key_t key)
 | 
						|
{
 | 
						|
    if (key >= PTHREAD_KEY_MAX)
 | 
						|
        return EINVAL;
 | 
						|
 | 
						|
    rt_enter_critical();
 | 
						|
    _thread_keys[key].is_used = 0;
 | 
						|
    _thread_keys[key].destructor = 0;
 | 
						|
    rt_exit_critical();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
RTM_EXPORT(pthread_key_delete);
 | 
						|
 |