support posix
1. posix pthread.h: pthread, pthread_barrier, pthread_cond, pthread_mutex, , pthread_rwlock, pthread_spin, etc 2. posix semaphore.h: sem_* 3. posix mqueue.h: mq_* 4. posix time.h: timer_* 5. to support posix, add tos_barrier, tos_bitmap, tos_rwlock, tos_stopwatch, change name of k_task_t from a char * pointer to a char array. 6. sample, see examples\posix 7. project, see board\TencentOS_tiny_EVB_MX_Plus\KEIL\posix
This commit is contained in:
302
osal/posix/pthread_prv.c
Normal file
302
osal/posix/pthread_prv.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos_k.h"
|
||||
|
||||
#include "pthread.h"
|
||||
#include "private/pthread.h"
|
||||
|
||||
__STATIC__ k_mutex_t pthread_mutex;
|
||||
|
||||
__STATIC__ pthread_ctl_t *thread_ctl_table[PTHREAD_THREADS_MAX] = { 0 };
|
||||
|
||||
__STATIC__ pthread_key_ctl_t pthread_key_ctl;
|
||||
|
||||
__KNL__ pthread_ctl_t *pthread_ctl_self(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int i = 0;
|
||||
k_task_t *self_task;
|
||||
pthread_ctl_t *the_info;
|
||||
|
||||
self_task = tos_task_curr_task_get();
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
|
||||
the_info = thread_ctl_table[i];
|
||||
if (the_info && the_info->the_ktask == self_task) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return the_info;
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
__KNL__ pthread_ctl_t *pthread_ctl_by_id(pthread_t id)
|
||||
{
|
||||
pthread_ctl_t *the_ctl;
|
||||
|
||||
the_ctl = thread_ctl_table[id];
|
||||
|
||||
if (!the_ctl) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
if (the_ctl->id != id) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
if (the_ctl->threadstate == PTHREAD_STATE_EXITED) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
return the_ctl;
|
||||
}
|
||||
|
||||
__KNL__ int pthread_id_add(pthread_t id, pthread_ctl_t *info)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
if (id < 0 ||
|
||||
id >= TOS_COUNT_OF(thread_ctl_table) ||
|
||||
thread_ctl_table[id]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
thread_ctl_table[id] = info;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ pthread_t pthread_id_alloc(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int i = 0;
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
|
||||
if (!thread_ctl_table[i]) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return (pthread_t)i;
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return -1;
|
||||
}
|
||||
|
||||
__KNL__ int pthread_id_free(pthread_t id)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
if (id < 0 ||
|
||||
id >= TOS_COUNT_OF(thread_ctl_table) ||
|
||||
!thread_ctl_table[id]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
thread_ctl_table[id] = K_NULL;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ void pthread_data_clear(pthread_key_t key)
|
||||
{
|
||||
int i = 0;
|
||||
pthread_ctl_t *the_ctl;
|
||||
|
||||
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
|
||||
the_ctl = thread_ctl_table[i];
|
||||
if (the_ctl && the_ctl->thread_data) {
|
||||
the_ctl->thread_data[key] = K_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__KNL__ int pthread_key_ctl_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (tos_bitmap_create_full(&pthread_key_ctl.key_bitmap,
|
||||
pthread_key_ctl.key_bitmap_tbl,
|
||||
PTHREAD_KEYS_MAX) != K_ERR_NONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < PTHREAD_KEYS_MAX; ++i) {
|
||||
pthread_key_ctl.destructors[i] = K_NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ pthread_key_t pthread_key_alloc(void)
|
||||
{
|
||||
int lsb;
|
||||
|
||||
lsb = tos_bitmap_lsb(&pthread_key_ctl.key_bitmap);
|
||||
|
||||
if (lsb > PTHREAD_KEYS_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_bitmap_reset(&pthread_key_ctl.key_bitmap, lsb);
|
||||
|
||||
return (pthread_key_t)lsb;
|
||||
}
|
||||
|
||||
__KNL__ int pthread_key_is_alloc(pthread_key_t key)
|
||||
{
|
||||
if (key > PTHREAD_KEYS_MAX || key < 0) {
|
||||
return K_FALSE;
|
||||
}
|
||||
|
||||
return tos_bitmap_is_reset(&pthread_key_ctl.key_bitmap, key);
|
||||
}
|
||||
|
||||
__KNL__ int pthread_key_free(pthread_key_t key)
|
||||
{
|
||||
if (key > PTHREAD_KEYS_MAX || key < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
|
||||
/* what we created is a full bitmap, if the bit is set means it is not used */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* make it avaliable again */
|
||||
tos_bitmap_set(&pthread_key_ctl.key_bitmap, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ int pthread_key_destructor_register(pthread_key_t key, key_destructor_t destructor)
|
||||
{
|
||||
if (key > PTHREAD_KEYS_MAX || key < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
|
||||
/* what we created is a full bitmap, if the bit is set means it is not used */
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_key_ctl.destructors[key] = destructor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__STATIC__ int pthread_key_destructor_is_register(pthread_key_t key)
|
||||
{
|
||||
if (key > PTHREAD_KEYS_MAX || key < 0) {
|
||||
return K_FALSE;
|
||||
}
|
||||
|
||||
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
|
||||
/* what we created is a full bitmap, if the bit is set means it is not used */
|
||||
return K_FALSE;
|
||||
}
|
||||
|
||||
return pthread_key_ctl.destructors[key] != K_NULL;
|
||||
}
|
||||
|
||||
__KNL__ key_destructor_t pthread_key_destructor_get(pthread_key_t key)
|
||||
{
|
||||
if (!pthread_key_destructor_is_register(key)) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
return pthread_key_ctl.destructors[key];
|
||||
}
|
||||
|
||||
__KNL__ int pthread_ctl_reap(int pthreads_ready2reap)
|
||||
{
|
||||
int i = 0;
|
||||
pthread_ctl_t *the_ctl;
|
||||
int pthreads_reaped = 0;
|
||||
|
||||
if (pthreads_ready2reap == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; pthreads_ready2reap && i < TOS_COUNT_OF(thread_ctl_table); ++i) {
|
||||
the_ctl = thread_ctl_table[i];
|
||||
if (!the_ctl || the_ctl->threadstate != PTHREAD_STATE_EXITED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pthread_id_free((pthread_t)i);
|
||||
|
||||
tos_sem_destroy(&the_ctl->joinner_sem);
|
||||
|
||||
if (the_ctl->stackaddr) {
|
||||
/* the_ctl is just on this stack */
|
||||
tos_mmheap_free(the_ctl->stackaddr);
|
||||
}
|
||||
|
||||
--pthreads_ready2reap;
|
||||
++pthreads_reaped;
|
||||
}
|
||||
|
||||
return pthreads_reaped;
|
||||
}
|
||||
|
||||
__KNL__ void pthread_lock(void)
|
||||
{
|
||||
tos_mutex_pend(&pthread_mutex);
|
||||
}
|
||||
|
||||
__KNL__ void pthread_unlock(void)
|
||||
{
|
||||
tos_mutex_post(&pthread_mutex);
|
||||
}
|
||||
|
||||
__KNL__ int pthread_lock_init(void)
|
||||
{
|
||||
if (tos_mutex_create(&pthread_mutex) != K_ERR_NONE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__KNL__ int pthread_init(void)
|
||||
{
|
||||
if (pthread_lock_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pthread_key_ctl_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user