19c6d7c21Sopenharmony_ci/*
29c6d7c21Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
39c6d7c21Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49c6d7c21Sopenharmony_ci * you may not use this file except in compliance with the License.
59c6d7c21Sopenharmony_ci * You may obtain a copy of the License at
69c6d7c21Sopenharmony_ci *
79c6d7c21Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89c6d7c21Sopenharmony_ci *
99c6d7c21Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109c6d7c21Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119c6d7c21Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129c6d7c21Sopenharmony_ci * See the License for the specific language governing permissions and
139c6d7c21Sopenharmony_ci * limitations under the License.
149c6d7c21Sopenharmony_ci */
159c6d7c21Sopenharmony_ci#include "thread_adapter.h"
169c6d7c21Sopenharmony_ci#include <pthread.h>
179c6d7c21Sopenharmony_ci#include <unistd.h>
189c6d7c21Sopenharmony_ci#include "common.h"
199c6d7c21Sopenharmony_ci#include "memory_adapter.h"
209c6d7c21Sopenharmony_ci#define PRI_BUTT 39
219c6d7c21Sopenharmony_ci#define MIN_STACK_SIZE 0x8000
229c6d7c21Sopenharmony_cistatic int g_threadCount = 0;
239c6d7c21Sopenharmony_cistatic pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
249c6d7c21Sopenharmony_cistatic pthread_key_t g_localKey = -1;
259c6d7c21Sopenharmony_cistatic pthread_once_t g_localKeyOnce = PTHREAD_ONCE_INIT;
269c6d7c21Sopenharmony_ci
279c6d7c21Sopenharmony_ciMutexId MUTEX_InitValue()
289c6d7c21Sopenharmony_ci{
299c6d7c21Sopenharmony_ci    pthread_mutex_t *mutex = SAMGR_Malloc(sizeof(pthread_mutex_t));
309c6d7c21Sopenharmony_ci    if (mutex == NULL) {
319c6d7c21Sopenharmony_ci        return NULL;
329c6d7c21Sopenharmony_ci    }
339c6d7c21Sopenharmony_ci    (void)pthread_mutex_init(mutex, NULL);
349c6d7c21Sopenharmony_ci    return (MutexId)mutex;
359c6d7c21Sopenharmony_ci}
369c6d7c21Sopenharmony_ci
379c6d7c21Sopenharmony_civoid MUTEX_Lock(MutexId mutex)
389c6d7c21Sopenharmony_ci{
399c6d7c21Sopenharmony_ci    if (mutex == NULL) {
409c6d7c21Sopenharmony_ci        return;
419c6d7c21Sopenharmony_ci    }
429c6d7c21Sopenharmony_ci    pthread_mutex_lock((pthread_mutex_t *)mutex);
439c6d7c21Sopenharmony_ci}
449c6d7c21Sopenharmony_ci
459c6d7c21Sopenharmony_civoid MUTEX_Unlock(MutexId mutex)
469c6d7c21Sopenharmony_ci{
479c6d7c21Sopenharmony_ci    if (mutex == NULL) {
489c6d7c21Sopenharmony_ci        return;
499c6d7c21Sopenharmony_ci    }
509c6d7c21Sopenharmony_ci    pthread_mutex_unlock((pthread_mutex_t *)mutex);
519c6d7c21Sopenharmony_ci}
529c6d7c21Sopenharmony_ci
539c6d7c21Sopenharmony_civoid MUTEX_GlobalLock(void)
549c6d7c21Sopenharmony_ci{
559c6d7c21Sopenharmony_ci    pthread_mutex_lock(&g_mutex);
569c6d7c21Sopenharmony_ci}
579c6d7c21Sopenharmony_ci
589c6d7c21Sopenharmony_civoid MUTEX_GlobalUnlock(void)
599c6d7c21Sopenharmony_ci{
609c6d7c21Sopenharmony_ci    pthread_mutex_unlock(&g_mutex);
619c6d7c21Sopenharmony_ci}
629c6d7c21Sopenharmony_ci
639c6d7c21Sopenharmony_cistatic void KeyCreate()
649c6d7c21Sopenharmony_ci{
659c6d7c21Sopenharmony_ci    (void) pthread_key_create(&g_localKey, NULL);
669c6d7c21Sopenharmony_ci}
679c6d7c21Sopenharmony_ci
689c6d7c21Sopenharmony_ciThreadId THREAD_Create(Runnable run, void *argv, const ThreadAttr *attr)
699c6d7c21Sopenharmony_ci{
709c6d7c21Sopenharmony_ci    pthread_attr_t threadAttr;
719c6d7c21Sopenharmony_ci    pthread_attr_init(&threadAttr);
729c6d7c21Sopenharmony_ci    pthread_attr_setstacksize(&threadAttr, (attr->stackSize | MIN_STACK_SIZE));
739c6d7c21Sopenharmony_ci#ifdef SAMGR_LINUX_ADAPTER
749c6d7c21Sopenharmony_ci    struct sched_param sched = {attr->priority};
759c6d7c21Sopenharmony_ci#else
769c6d7c21Sopenharmony_ci    struct sched_param sched = {PRI_BUTT - attr->priority};
779c6d7c21Sopenharmony_ci#endif
789c6d7c21Sopenharmony_ci    pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED);
799c6d7c21Sopenharmony_ci    pthread_attr_setschedpolicy(&threadAttr, SCHED_RR);
809c6d7c21Sopenharmony_ci    pthread_attr_setschedparam(&threadAttr, &sched);
819c6d7c21Sopenharmony_ci    (void) pthread_once(&g_localKeyOnce, KeyCreate);
829c6d7c21Sopenharmony_ci    pthread_t threadId = 0;
839c6d7c21Sopenharmony_ci    int errno = pthread_create(&threadId, &threadAttr, run, argv);
849c6d7c21Sopenharmony_ci    if (errno != 0) {
859c6d7c21Sopenharmony_ci        return NULL;
869c6d7c21Sopenharmony_ci    }
879c6d7c21Sopenharmony_ci
889c6d7c21Sopenharmony_ci    MUTEX_GlobalLock();
899c6d7c21Sopenharmony_ci    g_threadCount++;
909c6d7c21Sopenharmony_ci    MUTEX_GlobalUnlock();
919c6d7c21Sopenharmony_ci    return (ThreadId)threadId;
929c6d7c21Sopenharmony_ci}
939c6d7c21Sopenharmony_ci
949c6d7c21Sopenharmony_ciint THREAD_Total(void)
959c6d7c21Sopenharmony_ci{
969c6d7c21Sopenharmony_ci    return g_threadCount;
979c6d7c21Sopenharmony_ci}
989c6d7c21Sopenharmony_ci
999c6d7c21Sopenharmony_civoid *THREAD_GetThreadLocal(void)
1009c6d7c21Sopenharmony_ci{
1019c6d7c21Sopenharmony_ci    if (g_localKey == -1) {
1029c6d7c21Sopenharmony_ci        (void) pthread_once(&g_localKeyOnce, KeyCreate);
1039c6d7c21Sopenharmony_ci    }
1049c6d7c21Sopenharmony_ci    return pthread_getspecific(g_localKey);
1059c6d7c21Sopenharmony_ci}
1069c6d7c21Sopenharmony_ci
1079c6d7c21Sopenharmony_civoid THREAD_SetThreadLocal(const void *local)
1089c6d7c21Sopenharmony_ci{
1099c6d7c21Sopenharmony_ci    if (g_localKey == -1) {
1109c6d7c21Sopenharmony_ci        (void) pthread_once(&g_localKeyOnce, KeyCreate);
1119c6d7c21Sopenharmony_ci    }
1129c6d7c21Sopenharmony_ci    pthread_setspecific(g_localKey, local);
1139c6d7c21Sopenharmony_ci}
114