* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* CBB is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* cm_thread.h
*
*
* IDENTIFICATION
* src/cm_concurrency/cm_thread.h
*
* -------------------------------------------------------------------------
*/
#ifndef __CM_THREAD_H__
#define __CM_THREAD_H__
#include "cm_defs.h"
#include "cm_error.h"
#include "cm_atomic.h"
#include "cm_epoll.h"
#ifdef WIN32
#else
#include <pthread.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sched.h>
#include <sys/eventfd.h>
#include <semaphore.h>
#endif
#ifndef WIN32
#include <sys/types.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
typedef CRITICAL_SECTION thread_lock_t;
#define thread_local_var __declspec(thread)
typedef HANDLE cm_sem_t;
#else
typedef pthread_mutex_t thread_lock_t;
#define thread_local_var __thread
typedef sem_t cm_sem_t;
#endif
#define DFLT_THREAD_GUARD_SIZE 4096
typedef struct st_cm_thread_eventfd {
atomic_t wait_session_cnt;
int32 epfd;
int32 efd;
} cm_thread_eventfd_t;
void cm_init_eventfd(cm_thread_eventfd_t *etfd);
void cm_timedwait_eventfd(cm_thread_eventfd_t *etfd, int32 timeout_ms);
void cm_wakeup_eventfd(cm_thread_eventfd_t *etfd);
void cm_release_eventfd(cm_thread_eventfd_t *etfd);
typedef struct st_cm_thread_cond {
#ifdef WIN32
HANDLE sem;
atomic32_t count;
#else
pthread_mutex_t lock;
pthread_cond_t cond;
pthread_condattr_t attr;
#endif
} cm_thread_cond_t;
void cm_init_cond(cm_thread_cond_t *cond);
bool32 cm_wait_cond(cm_thread_cond_t *cond, uint32 ms);
void cm_release_cond(cm_thread_cond_t *cond);
void cm_release_cond_signal(cm_thread_cond_t *cond);
void cm_destory_cond(cm_thread_cond_t *cond);
void cm_init_thread_lock(thread_lock_t *lock);
void cm_thread_lock(thread_lock_t *lock);
void cm_thread_unlock(thread_lock_t *lock);
void cm_destroy_thread_lock(thread_lock_t *lock);
typedef struct st_thread {
#ifdef WIN32
DWORD id;
HANDLE handle;
#else
pthread_t id;
#endif
volatile bool32 closed;
void *entry;
void *argument;
int32 result;
uint32 stack_size;
void *reg_data;
char *stack_base;
} thread_t;
typedef void (*thread_entry_t)(thread_t *thread);
status_t cm_create_thread(thread_entry_t entry, uint32 stack_size, void *argument, thread_t *thread);
void cm_close_thread(thread_t *thread);
void cm_close_thread_nowait(thread_t *thread);
void cm_close_thread_with_sem(thread_t *thread, cm_sem_t *sem);
uint32 cm_get_current_thread_id(void);
void cm_release_thread(thread_t *thread);
void cm_switch_stack_base(thread_t *thread, char *stack_base, char **org_base);
#ifdef __linux
#define cm_set_thread_name(x) (void)prctl(PR_SET_NAME, x)
#else
#define cm_set_thread_name(x)
#endif
#ifdef WIN32
typedef DWORD cpu_set_t;
#endif
void cm_sem_init(cm_sem_t *sem);
void cm_sem_post(cm_sem_t *sem);
void cm_sem_wait(cm_sem_t *sem);
void cm_sem_destroy(cm_sem_t *sem);
#ifdef __cplusplus
}
#endif
#endif