Merge pull request #1392 from bytecodealliance/main
Merge main into dev/socket
This commit is contained in:
@ -55,6 +55,7 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
|
||||
@ -195,6 +195,48 @@ os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
korp_sem *
|
||||
os_sem_open(const char *name, int oflags, int mode, int val)
|
||||
{
|
||||
return sem_open(name, oflags, mode, val);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_close(korp_sem *sem)
|
||||
{
|
||||
return sem_close(sem);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_wait(korp_sem *sem)
|
||||
{
|
||||
return sem_wait(sem);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_trywait(korp_sem *sem)
|
||||
{
|
||||
return sem_trywait(sem);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_post(korp_sem *sem)
|
||||
{
|
||||
return sem_post(sem);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_getvalue(korp_sem *sem, int *sval)
|
||||
{
|
||||
return sem_getvalue(sem, sval);
|
||||
}
|
||||
|
||||
int
|
||||
os_sem_unlink(const char *name)
|
||||
{
|
||||
return sem_unlink(name);
|
||||
}
|
||||
|
||||
static void
|
||||
msec_nsec_to_abstime(struct timespec *ts, uint64 usec)
|
||||
{
|
||||
|
||||
@ -56,6 +56,7 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
|
||||
@ -58,3 +58,193 @@ os_usleep(uint32 usec)
|
||||
{
|
||||
return usleep(usec);
|
||||
}
|
||||
|
||||
/* Below parts of readv & writev are ported from Nuttx, under Apache License
|
||||
* v2.0 */
|
||||
|
||||
ssize_t
|
||||
readv(int fildes, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
ssize_t ntotal;
|
||||
ssize_t nread;
|
||||
size_t remaining;
|
||||
uint8_t *buffer;
|
||||
int i;
|
||||
|
||||
/* Process each entry in the struct iovec array */
|
||||
|
||||
for (i = 0, ntotal = 0; i < iovcnt; i++) {
|
||||
/* Ignore zero-length reads */
|
||||
|
||||
if (iov[i].iov_len > 0) {
|
||||
buffer = iov[i].iov_base;
|
||||
remaining = iov[i].iov_len;
|
||||
|
||||
/* Read repeatedly as necessary to fill buffer */
|
||||
|
||||
do {
|
||||
/* NOTE: read() is a cancellation point */
|
||||
|
||||
nread = read(fildes, buffer, remaining);
|
||||
|
||||
/* Check for a read error */
|
||||
|
||||
if (nread < 0) {
|
||||
return nread;
|
||||
}
|
||||
|
||||
/* Check for an end-of-file condition */
|
||||
|
||||
else if (nread == 0) {
|
||||
return ntotal;
|
||||
}
|
||||
|
||||
/* Update pointers and counts in order to handle partial
|
||||
* buffer reads.
|
||||
*/
|
||||
|
||||
buffer += nread;
|
||||
remaining -= nread;
|
||||
ntotal += nread;
|
||||
} while (remaining > 0);
|
||||
}
|
||||
}
|
||||
|
||||
return ntotal;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
writev(int fildes, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
ssize_t ntotal;
|
||||
ssize_t nwritten;
|
||||
size_t remaining;
|
||||
uint8_t *buffer;
|
||||
int i;
|
||||
|
||||
/* Process each entry in the struct iovec array */
|
||||
|
||||
for (i = 0, ntotal = 0; i < iovcnt; i++) {
|
||||
/* Ignore zero-length writes */
|
||||
|
||||
if (iov[i].iov_len > 0) {
|
||||
buffer = iov[i].iov_base;
|
||||
remaining = iov[i].iov_len;
|
||||
|
||||
/* Write repeatedly as necessary to write the entire buffer */
|
||||
|
||||
do {
|
||||
/* NOTE: write() is a cancellation point */
|
||||
|
||||
nwritten = write(fildes, buffer, remaining);
|
||||
|
||||
/* Check for a write error */
|
||||
|
||||
if (nwritten < 0) {
|
||||
return ntotal ? ntotal : -1;
|
||||
}
|
||||
|
||||
/* Update pointers and counts in order to handle partial
|
||||
* buffer writes.
|
||||
*/
|
||||
|
||||
buffer += nwritten;
|
||||
remaining -= nwritten;
|
||||
ntotal += nwritten;
|
||||
} while (remaining > 0);
|
||||
}
|
||||
}
|
||||
|
||||
return ntotal;
|
||||
}
|
||||
|
||||
int
|
||||
openat(int fd, const char *path, int oflags, ...)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
fstatat(int fd, const char *path, struct stat *buf, int flag)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
mkdirat(int fd, const char *path, mode_t mode)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
readlinkat(int fd, const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
linkat(int fd1, const char *path1, int fd2, const char *path2, int flag)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
renameat(int fromfd, const char *from, int tofd, const char *to)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
symlinkat(const char *target, int fd, const char *path)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
unlinkat(int fd, const char *path, int flag)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
utimensat(int fd, const char *path, const struct timespec ts[2], int flag)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
DIR *
|
||||
fdopendir(int fd)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ftruncate(int fd, off_t length)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
futimens(int fd, const struct timespec times[2])
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
nanosleep(const struct timespec *req, struct timespec *rem)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
@ -44,6 +44,25 @@ os_mutex_init(korp_mutex *mutex)
|
||||
return pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
os_recursive_mutex_init(korp_mutex *mutex)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pthread_mutexattr_t mattr;
|
||||
|
||||
assert(mutex);
|
||||
ret = pthread_mutexattr_init(&mattr);
|
||||
if (ret)
|
||||
return BHT_ERROR;
|
||||
|
||||
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
ret = pthread_mutex_init(mutex, &mattr);
|
||||
pthread_mutexattr_destroy(&mattr);
|
||||
|
||||
return ret == 0 ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_destroy(korp_mutex *mutex)
|
||||
{
|
||||
@ -206,3 +225,9 @@ os_cond_signal(korp_cond *cond)
|
||||
{
|
||||
return pthread_cond_signal(cond);
|
||||
}
|
||||
|
||||
int
|
||||
os_cond_broadcast(korp_cond *cond)
|
||||
{
|
||||
return pthread_cond_broadcast(cond);
|
||||
}
|
||||
@ -17,6 +17,10 @@
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_timer.h"
|
||||
@ -35,12 +39,73 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef unsigned int korp_sem;
|
||||
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)
|
||||
|
||||
/* Default thread priority */
|
||||
#define BH_THREAD_DEFAULT_PRIORITY 5
|
||||
|
||||
/* Special value for tv_nsec field of timespec */
|
||||
|
||||
#define UTIME_NOW ((1l << 30) - 1l)
|
||||
#ifndef __cplusplus
|
||||
#define UTIME_OMIT ((1l << 30) - 2l)
|
||||
#endif
|
||||
|
||||
#ifdef DT_UNKNOWN
|
||||
#undef DT_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifdef DT_REG
|
||||
#undef DT_REG
|
||||
#endif
|
||||
|
||||
#ifdef DT_DIR
|
||||
#undef DT_DIR
|
||||
#endif
|
||||
|
||||
/* Below parts of d_type define are ported from Nuttx, under Apache License v2.0
|
||||
*/
|
||||
|
||||
/* File type code for the d_type field in dirent structure.
|
||||
* Note that because of the simplified filesystem organization of the NuttX,
|
||||
* top-level, pseudo-file system, an inode can be BOTH a file and a directory
|
||||
*/
|
||||
|
||||
#define DTYPE_UNKNOWN 0
|
||||
#define DTYPE_FIFO 1
|
||||
#define DTYPE_CHR 2
|
||||
#define DTYPE_SEM 3
|
||||
#define DTYPE_DIRECTORY 4
|
||||
#define DTYPE_MQ 5
|
||||
#define DTYPE_BLK 6
|
||||
#define DTYPE_SHM 7
|
||||
#define DTYPE_FILE 8
|
||||
#define DTYPE_MTD 9
|
||||
#define DTYPE_LINK 10
|
||||
#define DTYPE_SOCK 12
|
||||
|
||||
/* The d_type field of the dirent structure is not specified by POSIX. It
|
||||
* is a non-standard, 4.5BSD extension that is implemented by most OSs. A
|
||||
* POSIX compliant OS may not implement the d_type field at all. Many OS's
|
||||
* (including glibc) may use the following alternative naming for the file
|
||||
* type names:
|
||||
*/
|
||||
|
||||
#define DT_UNKNOWN DTYPE_UNKNOWN
|
||||
#define DT_FIFO DTYPE_FIFO
|
||||
#define DT_CHR DTYPE_CHR
|
||||
#define DT_SEM DTYPE_SEM
|
||||
#define DT_DIR DTYPE_DIRECTORY
|
||||
#define DT_MQ DTYPE_MQ
|
||||
#define DT_BLK DTYPE_BLK
|
||||
#define DT_SHM DTYPE_SHM
|
||||
#define DT_REG DTYPE_FILE
|
||||
#define DT_MTD DTYPE_MTD
|
||||
#define DT_LNK DTYPE_LINK
|
||||
#define DT_SOCK DTYPE_SOCK
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -195,6 +195,91 @@ os_cond_signal(korp_cond *cond);
|
||||
int
|
||||
os_cond_broadcast(korp_cond *cond);
|
||||
|
||||
/**
|
||||
* Creates a new POSIX-like semaphore or opens an existing
|
||||
* semaphore. The semaphore is identified by name. For details of
|
||||
* the construction of name, please refer to
|
||||
* https://man7.org/linux/man-pages/man3/sem_open.3.html.
|
||||
*
|
||||
* @param name semaphore name
|
||||
* @param oflasg specifies flags that control the operation of the call
|
||||
* @param mode permission flags
|
||||
* @param val initial value of the named semaphore.
|
||||
*
|
||||
* @return korp_sem * if success, NULL otherwise
|
||||
*/
|
||||
korp_sem *
|
||||
os_sem_open(const char *name, int oflags, int mode, int val);
|
||||
|
||||
/**
|
||||
* Closes the named semaphore referred to by sem,
|
||||
* allowing any resources that the system has allocated to the
|
||||
* calling process for this semaphore to be freed.
|
||||
*
|
||||
* @param sem
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_close(korp_sem *sem);
|
||||
|
||||
/**
|
||||
* Decrements (locks) the semaphore pointed to by sem.
|
||||
* If the semaphore's value is greater than zero, then the decrement
|
||||
* proceeds, and the function returns, immediately. If the
|
||||
* semaphore currently has the value zero, then the call blocks
|
||||
* until either it becomes possible to perform the decrement (i.e.,
|
||||
* the semaphore value rises above zero), or a signal handler
|
||||
* interrupts the call.
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_wait(korp_sem *sem);
|
||||
|
||||
/**
|
||||
* Is the same as sem_wait(), except that if the
|
||||
* decrement cannot be immediately performed, then call returns an
|
||||
* error (errno set to EAGAIN) instead of blocking.
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_trywait(korp_sem *sem);
|
||||
|
||||
/**
|
||||
* Increments (unlocks) the semaphore pointed to by sem.
|
||||
* If the semaphore's value consequently becomes greater than zero,
|
||||
* then another process or thread blocked in a sem_wait(3) call will
|
||||
* be woken up and proceed to lock the semaphore.
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_post(korp_sem *sem);
|
||||
|
||||
/**
|
||||
* Places the current value of the semaphore pointed
|
||||
* to sem into the integer pointed to by sval.
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_getvalue(korp_sem *sem, int *sval);
|
||||
|
||||
/**
|
||||
* Remove the named semaphore referred to by name.
|
||||
* The semaphore name is removed immediately. The semaphore is
|
||||
* destroyed once all other processes that have the semaphore open
|
||||
* close it.
|
||||
*
|
||||
* @param name semaphore name
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
int
|
||||
os_sem_unlink(const char *name);
|
||||
|
||||
/****************************************************
|
||||
* Section 2 *
|
||||
* Socket support *
|
||||
|
||||
@ -50,8 +50,9 @@ typedef pthread_t korp_thread;
|
||||
typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef unsigned int korp_sem;
|
||||
|
||||
typedef void (*os_print_function_t)(const char *message);
|
||||
typedef int (*os_print_function_t)(const char *message);
|
||||
void
|
||||
os_set_print_function(os_print_function_t pf);
|
||||
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
#include "platform_api_extension.h"
|
||||
#include "sgx_rsrv_mem_mngr.h"
|
||||
|
||||
#define FIXED_BUFFER_SIZE (1 << 9)
|
||||
|
||||
static os_print_function_t print_function = NULL;
|
||||
|
||||
int
|
||||
@ -57,31 +55,37 @@ os_set_print_function(os_print_function_t pf)
|
||||
print_function = pf;
|
||||
}
|
||||
|
||||
#define FIXED_BUFFER_SIZE 4096
|
||||
|
||||
int
|
||||
os_printf(const char *message, ...)
|
||||
{
|
||||
int bytes_written = 0;
|
||||
|
||||
if (print_function != NULL) {
|
||||
char msg[FIXED_BUFFER_SIZE] = { '\0' };
|
||||
va_list ap;
|
||||
va_start(ap, message);
|
||||
vsnprintf(msg, FIXED_BUFFER_SIZE, message, ap);
|
||||
va_end(ap);
|
||||
print_function(msg);
|
||||
bytes_written += print_function(msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
int
|
||||
os_vprintf(const char *format, va_list arg)
|
||||
{
|
||||
int bytes_written = 0;
|
||||
|
||||
if (print_function != NULL) {
|
||||
char msg[FIXED_BUFFER_SIZE] = { '\0' };
|
||||
vsnprintf(msg, FIXED_BUFFER_SIZE, format, arg);
|
||||
print_function(msg);
|
||||
bytes_written += print_function(msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
char *
|
||||
|
||||
@ -55,6 +55,7 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -38,6 +39,7 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
typedef thread_t korp_thread;
|
||||
typedef kernel_pid_t korp_tid;
|
||||
typedef mutex_t korp_mutex;
|
||||
typedef unsigned int korp_sem;
|
||||
|
||||
/* typedef sema_t korp_sem; */
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ typedef rt_thread_t korp_tid;
|
||||
typedef struct rt_mutex korp_mutex;
|
||||
typedef struct rt_thread korp_cond;
|
||||
typedef struct rt_thread korp_thread;
|
||||
typedef unsigned int korp_sem;
|
||||
|
||||
typedef rt_uint8_t uint8_t;
|
||||
typedef rt_int8_t int8_t;
|
||||
|
||||
@ -54,6 +54,7 @@ typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
|
||||
@ -43,6 +43,17 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
||||
/* integer overflow */
|
||||
return NULL;
|
||||
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
/**
|
||||
* Allocate memory at the highest possible address if the
|
||||
* request size is large, or LLVM JIT might report error:
|
||||
* IMAGE_REL_AMD64_ADDR32NB relocation requires an ordered
|
||||
* section layout.
|
||||
*/
|
||||
if (request_size > 10 * BH_MB)
|
||||
alloc_type |= MEM_TOP_DOWN;
|
||||
#endif
|
||||
|
||||
protect = access_to_win32_flags(prot);
|
||||
if (protect != PAGE_NOACCESS) {
|
||||
alloc_type |= MEM_COMMIT;
|
||||
|
||||
@ -37,6 +37,10 @@ typedef struct os_thread_data {
|
||||
korp_mutex wait_lock;
|
||||
/* Waiting list of other threads who are joining this thread */
|
||||
os_thread_wait_list thread_wait_list;
|
||||
/* Whether the thread has exited */
|
||||
bool thread_exited;
|
||||
/* Thread return value */
|
||||
void *thread_retval;
|
||||
} os_thread_data;
|
||||
|
||||
static bool is_thread_sys_inited = false;
|
||||
@ -44,6 +48,9 @@ static bool is_thread_sys_inited = false;
|
||||
/* Thread data of supervisor thread */
|
||||
static os_thread_data supervisor_thread_data;
|
||||
|
||||
/* Thread data list lock */
|
||||
static korp_mutex thread_data_list_lock;
|
||||
|
||||
/* Thread data key */
|
||||
static DWORD thread_data_key;
|
||||
|
||||
@ -90,7 +97,10 @@ os_thread_sys_init()
|
||||
if (!TlsSetValue(thread_data_key, &supervisor_thread_data))
|
||||
goto fail4;
|
||||
|
||||
if ((module = GetModuleHandle((LPSTR) "kernel32"))) {
|
||||
if (os_mutex_init(&thread_data_list_lock) != BHT_OK)
|
||||
goto fail5;
|
||||
|
||||
if ((module = GetModuleHandle((LPCTSTR) "kernel32"))) {
|
||||
*(void **)&GetCurrentThreadStackLimits_Kernel32 =
|
||||
GetProcAddress(module, "GetCurrentThreadStackLimits");
|
||||
}
|
||||
@ -98,6 +108,8 @@ os_thread_sys_init()
|
||||
is_thread_sys_inited = true;
|
||||
return BHT_OK;
|
||||
|
||||
fail5:
|
||||
TlsSetValue(thread_data_key, NULL);
|
||||
fail4:
|
||||
os_cond_destroy(&supervisor_thread_data.wait_cond);
|
||||
fail3:
|
||||
@ -113,6 +125,22 @@ void
|
||||
os_thread_sys_destroy()
|
||||
{
|
||||
if (is_thread_sys_inited) {
|
||||
os_thread_data *thread_data, *thread_data_next;
|
||||
|
||||
thread_data = supervisor_thread_data.next;
|
||||
while (thread_data) {
|
||||
thread_data_next = thread_data->next;
|
||||
|
||||
/* Destroy resources of thread data */
|
||||
os_cond_destroy(&thread_data->wait_cond);
|
||||
os_sem_destroy(&thread_data->wait_node.sem);
|
||||
os_mutex_destroy(&thread_data->wait_lock);
|
||||
BH_FREE(thread_data);
|
||||
|
||||
thread_data = thread_data_next;
|
||||
}
|
||||
|
||||
os_mutex_destroy(&thread_data_list_lock);
|
||||
os_cond_destroy(&supervisor_thread_data.wait_cond);
|
||||
os_mutex_destroy(&supervisor_thread_data.wait_lock);
|
||||
os_sem_destroy(&supervisor_thread_data.wait_node.sem);
|
||||
@ -148,13 +176,10 @@ os_thread_cleanup(void *retval)
|
||||
}
|
||||
thread_data->thread_wait_list = NULL;
|
||||
}
|
||||
/* Set thread status and thread return value */
|
||||
thread_data->thread_exited = true;
|
||||
thread_data->thread_retval = retval;
|
||||
os_mutex_unlock(&thread_data->wait_lock);
|
||||
|
||||
/* Destroy resources */
|
||||
os_cond_destroy(&thread_data->wait_cond);
|
||||
os_sem_destroy(&thread_data->wait_node.sem);
|
||||
os_mutex_destroy(&thread_data->wait_lock);
|
||||
BH_FREE(thread_data);
|
||||
}
|
||||
|
||||
static unsigned __stdcall os_thread_wrapper(void *arg)
|
||||
@ -224,6 +249,13 @@ os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
|
||||
os_mutex_unlock(&parent->wait_lock);
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
/* Add thread data into thread data list */
|
||||
os_mutex_lock(&thread_data_list_lock);
|
||||
thread_data->next = supervisor_thread_data.next;
|
||||
supervisor_thread_data.next = thread_data;
|
||||
os_mutex_unlock(&thread_data_list_lock);
|
||||
|
||||
/* Wait for the thread routine to set thread_data's tid
|
||||
and add thread_data to thread data list */
|
||||
os_cond_wait(&parent->wait_cond, &parent->wait_lock);
|
||||
@ -271,6 +303,16 @@ os_thread_join(korp_tid thread, void **p_retval)
|
||||
bh_assert(thread_data);
|
||||
|
||||
os_mutex_lock(&thread_data->wait_lock);
|
||||
|
||||
if (thread_data->thread_exited) {
|
||||
/* Thread has exited */
|
||||
if (p_retval)
|
||||
*p_retval = thread_data->thread_retval;
|
||||
os_mutex_unlock(&thread_data->wait_lock);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
/* Thread is running */
|
||||
if (!thread_data->thread_wait_list)
|
||||
thread_data->thread_wait_list = &curr_thread_data->wait_node;
|
||||
else {
|
||||
@ -280,6 +322,7 @@ os_thread_join(korp_tid thread, void **p_retval)
|
||||
p = p->next;
|
||||
p->next = &curr_thread_data->wait_node;
|
||||
}
|
||||
|
||||
os_mutex_unlock(&thread_data->wait_lock);
|
||||
|
||||
/* Wait the sem */
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
typedef struct k_thread korp_thread;
|
||||
typedef korp_thread *korp_tid;
|
||||
typedef struct k_mutex korp_mutex;
|
||||
typedef unsigned int korp_sem;
|
||||
|
||||
struct os_thread_wait_node;
|
||||
typedef struct os_thread_wait_node *os_thread_wait_list;
|
||||
|
||||
Reference in New Issue
Block a user