add semaphore and sched implementation.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1056 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
5c148b6705
commit
32f6598912
@ -1,4 +1,5 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sched.h>
|
||||||
#include "pthread_internal.h"
|
#include "pthread_internal.h"
|
||||||
|
|
||||||
int pthread_system_init(void)
|
int pthread_system_init(void)
|
||||||
|
@ -39,13 +39,6 @@ typedef long pthread_barrierattr_t;
|
|||||||
typedef int pthread_key_t;
|
typedef int pthread_key_t;
|
||||||
typedef int pthread_once_t;
|
typedef int pthread_once_t;
|
||||||
|
|
||||||
/*
|
|
||||||
* Scheduling policies required by IEEE Std 1003.1-2001
|
|
||||||
*/
|
|
||||||
#define SCHED_OTHER 0 /* Behavior can be FIFO or RR, or not */
|
|
||||||
#define SCHED_FIFO 1
|
|
||||||
#define SCHED_RR 2
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS = 0,
|
PTHREAD_CANCEL_ASYNCHRONOUS = 0,
|
||||||
PTHREAD_CANCEL_ENABLE,
|
PTHREAD_CANCEL_ENABLE,
|
||||||
@ -78,10 +71,6 @@ enum {
|
|||||||
#define PTHREAD_SCOPE_PROCESS 0
|
#define PTHREAD_SCOPE_PROCESS 0
|
||||||
#define PTHREAD_SCOPE_SYSTEM 1
|
#define PTHREAD_SCOPE_SYSTEM 1
|
||||||
|
|
||||||
struct sched_param {
|
|
||||||
int sched_priority;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pthread_attr
|
struct pthread_attr
|
||||||
{
|
{
|
||||||
void* stack_base;
|
void* stack_base;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include "pthread.h"
|
#include "pthread.h"
|
||||||
|
#include "sched.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define DEFAULT_STACK_SIZE 2048
|
#define DEFAULT_STACK_SIZE 2048
|
||||||
|
@ -148,7 +148,7 @@ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
|
|
||||||
result = rt_sem_take(&(cond->sem), timeout);
|
result = rt_sem_take(&(cond->sem), timeout);
|
||||||
/* lock mutex again */
|
/* lock mutex again */
|
||||||
pthred_mutex_lock(mutex);
|
pthread_mutex_lock(mutex);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
#include <pthread.h>
|
|
||||||
#include <finsh.h>
|
|
||||||
|
|
||||||
#define _die_(x) do { rt_kprintf(x); RT_ASSERT(0); } while (0)
|
|
||||||
#define pr(x) do { rt_kprintf(x); } while (0)
|
|
||||||
#define sleep(n) rt_thread_sleep((n * RT_TICK_PER_SECOND)/1000)
|
|
||||||
#define alarm(n)
|
|
||||||
|
|
||||||
/* (0) once test */
|
|
||||||
void test0_ok() { pr("(once called) "); }
|
|
||||||
void test0_failed() { _die_("failed...\n"); }
|
|
||||||
void pth_t0() {
|
|
||||||
pthread_once_t v_once=PTHREAD_ONCE_INIT;
|
|
||||||
pr("\nTEST 0: once test:\n\n");
|
|
||||||
pr("testing once function... ");
|
|
||||||
pthread_once(&v_once,test0_ok);
|
|
||||||
pthread_once(&v_once,test0_failed);
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
FINSH_FUNCTION_EXPORT(pth_t0, pthread testcase0);
|
|
||||||
|
|
||||||
/* (1) mutex tests */
|
|
||||||
void test_rec_mutex() {
|
|
||||||
pthread_mutex_t tm;
|
|
||||||
pthread_mutexattr_t ta;
|
|
||||||
pthread_mutexattr_settype(&ta, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
pthread_mutex_init(&tm, &ta);
|
|
||||||
pr("testing recursive mutex... ");
|
|
||||||
alarm(5);
|
|
||||||
if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on unused rec-mutex (c=0)...\n");
|
|
||||||
if (tm.lock.owner!=pthread_self()) _die_("failed.. wrong owner....\n");
|
|
||||||
if (tm.lock.hold!=1) _die_("failed... wrong counting (c!=1)....\n");
|
|
||||||
if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on taken rec-mutex (c=1)...\n");
|
|
||||||
if (tm.lock.hold!=2) _die_("failed... wrong counting (c!=2)....\n");
|
|
||||||
if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on taken rec-mutex (c=2)...\n");
|
|
||||||
if (tm.lock.hold!=3) _die_("failed... wrong counting (c!=3)....\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=3)...\n");
|
|
||||||
if (tm.lock.hold!=2) _die_("failed... wrong counting (c!=2)....\n");
|
|
||||||
if (tm.lock.owner==0) _die_("failed... mutex has no owner?!?!\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=2)...\n");
|
|
||||||
if (tm.lock.hold!=1) _die_("failed... wrong counting (c!=1)....\n");
|
|
||||||
if (tm.lock.owner==0) _die_("failed... mutex has no owner?!?!\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=1)...\n");
|
|
||||||
if (tm.lock.hold!=0) _die_("failed... wrong counting (c!=0)....\n");
|
|
||||||
if (tm.lock.owner!=0) _die_("failed... mutex still owned ?!?!\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on free rec-mutex (c=0)...\n");
|
|
||||||
alarm(0);
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_err_mutex() {
|
|
||||||
pthread_mutex_t tm;
|
|
||||||
pthread_mutexattr_t ta;
|
|
||||||
|
|
||||||
pthread_mutexattr_settype(&ta, PTHREAD_MUTEX_ERRORCHECK);
|
|
||||||
pthread_mutex_init(&tm, &ta);
|
|
||||||
pr("testing errorcheck mutex... ");
|
|
||||||
alarm(5);
|
|
||||||
if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on unused errchk-mutex...\n");
|
|
||||||
if (tm.lock.owner!=pthread_self()) _die_("failed.. wrong owner....\n");
|
|
||||||
if (pthread_mutex_lock(&tm) != EDEADLK) _die_("failed... mutex_lock on taken errchk-mutex...\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken errchk-mutex...\n");
|
|
||||||
if (tm.lock.owner!=0) _die_("failed... mutex still owned ?!?!\n");
|
|
||||||
if (pthread_mutex_unlock(&tm) != EPERM) _die_("failed... mutex_unlock on free errchk-mutex...\n");
|
|
||||||
alarm(0);
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void pth_t1() {
|
|
||||||
pr("\nTEST 1: mutex test:\n\n");
|
|
||||||
test_rec_mutex();
|
|
||||||
test_err_mutex();
|
|
||||||
}
|
|
||||||
FINSH_FUNCTION_EXPORT(pth_t1, pthread testcase0);
|
|
||||||
|
|
||||||
void* thread(void*arg)
|
|
||||||
{
|
|
||||||
if (0) { arg=0; }
|
|
||||||
pr("(thread created) ");
|
|
||||||
sleep(1);
|
|
||||||
pr("(thread exit) ");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_thread() {
|
|
||||||
pthread_t t;
|
|
||||||
pr("testing basic thread creation and join... ");
|
|
||||||
if ((pthread_create(&t,0,thread,0))!=0) _die_("failed...\n");
|
|
||||||
if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_thread_join_detached() {
|
|
||||||
pthread_t t;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pr("testing for failing join of a detached thread... ");
|
|
||||||
pthread_attr_init(&attr);
|
|
||||||
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
|
|
||||||
if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed...\n");
|
|
||||||
if (pthread_join(t,0) == 0) _die_("failed... I had joined a detached thread !\n");
|
|
||||||
sleep(2);
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char alt_stack[4096];
|
|
||||||
void test_thread_alt_stack() {
|
|
||||||
pthread_t t;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pr("testing alternate thread stack... ");
|
|
||||||
pthread_attr_init(&attr);
|
|
||||||
pthread_attr_setstacksize(&attr,sizeof(alt_stack));
|
|
||||||
if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed... creating thread\n");
|
|
||||||
if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
|
|
||||||
pthread_attr_setstackaddr(&attr,alt_stack);
|
|
||||||
if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed... creating thread\n");
|
|
||||||
if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
|
|
||||||
pr("OK.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void pth_t2()
|
|
||||||
{
|
|
||||||
pr("\nTEST 2: thread creation & attributes:\n\n");
|
|
||||||
test_thread();
|
|
||||||
test_thread_join_detached();
|
|
||||||
test_thread_alt_stack();
|
|
||||||
}
|
|
||||||
FINSH_FUNCTION_EXPORT(pth_t2, pthread testcase1);
|
|
28
components/pthreads/sched.c
Normal file
28
components/pthreads/sched.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
int sched_yield(void)
|
||||||
|
{
|
||||||
|
rt_thread_yield();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sched_get_priority_min(int policy)
|
||||||
|
{
|
||||||
|
if (policy != SCHED_FIFO && policy != SCHED_RR)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sched_get_priority_max(int policy)
|
||||||
|
{
|
||||||
|
if (policy != SCHED_FIFO && policy != SCHED_RR)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
return RT_THREAD_PRIORITY_MAX - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sched_setscheduler(pid_t pid, int policy)
|
||||||
|
{
|
||||||
|
return ENOTSUP;
|
||||||
|
}
|
37
components/pthreads/sched.h
Normal file
37
components/pthreads/sched.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef __SCHED_H__
|
||||||
|
#define __SCHED_H__
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Thread scheduling policies */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SCHED_OTHER = 0,
|
||||||
|
SCHED_FIFO,
|
||||||
|
SCHED_RR,
|
||||||
|
SCHED_MIN = SCHED_OTHER,
|
||||||
|
SCHED_MAX = SCHED_RR
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sched_param
|
||||||
|
{
|
||||||
|
int sched_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int sched_yield(void);
|
||||||
|
int sched_get_priority_min(int policy);
|
||||||
|
int sched_get_priority_max(int policy);
|
||||||
|
int sched_setscheduler(pid_t pid, int policy);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,98 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
|
|
||||||
#include "sem.h"
|
|
||||||
|
|
||||||
int sem_close(sem_t *sem)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_destroy(sem_t *sem)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_unlink(const char *name)
|
|
||||||
{
|
|
||||||
return EACCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_getvalue(sem_t *sem, int *sval)
|
|
||||||
{
|
|
||||||
RT_ASSERT(sem != RT_NULL);
|
|
||||||
if (sval) *sval = sem->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
|
||||||
{
|
|
||||||
RT_ASSERT(sem != RT_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
sem_t *sem_open(const char *name, int oflag, ...)
|
|
||||||
{
|
|
||||||
rt_sem_t sem;
|
|
||||||
|
|
||||||
sem = RT_NULL;
|
|
||||||
if (oflag == O_CREAT)
|
|
||||||
{
|
|
||||||
sem = rt_sem_create(name, 1, RT_IPC_FLAG_FIFO);
|
|
||||||
if (sem == RT_NULL)
|
|
||||||
rt_set_errno(ENOSPC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oflag == O_EXCL)
|
|
||||||
{
|
|
||||||
rt_enter_critical();
|
|
||||||
/* find semaphore object */
|
|
||||||
rt_exit_critical();
|
|
||||||
|
|
||||||
if (sem == RT_NULL) rt_set_errno(ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_post(sem_t *sem)
|
|
||||||
{
|
|
||||||
rt_sem_release(sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
|
|
||||||
{
|
|
||||||
rt_err_t result;
|
|
||||||
rt_int32_t tick;
|
|
||||||
|
|
||||||
if (!sem || !abs_timeout) return EINVAL;
|
|
||||||
|
|
||||||
/* calculate os tick */
|
|
||||||
tick = abs_timeout->tv_sec/RT_TICK_PER_SECOND + (abs_timeout->tv_nsec/1000) * (1000/RT_TICK_PER_SECOND);
|
|
||||||
|
|
||||||
result = rt_sem_take(sem, tick);
|
|
||||||
if (result == -RT_ETIMEOUT) return ETIMEDOUT;
|
|
||||||
if (result == RT_EOK) return 0;
|
|
||||||
|
|
||||||
return EINTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_trywait(sem_t *sem)
|
|
||||||
{
|
|
||||||
rt_err_t result;
|
|
||||||
|
|
||||||
if (!sem) return EINVAL;
|
|
||||||
|
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
|
||||||
if (result == -RT_ETIMEOUT) return EAGAIN;
|
|
||||||
if (result == RT_EOK) return 0;
|
|
||||||
|
|
||||||
return EINTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_wait(sem_t *sem)
|
|
||||||
{
|
|
||||||
rt_err_t result;
|
|
||||||
|
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
|
||||||
if (result == RT_EOK) return 0;
|
|
||||||
|
|
||||||
return EINTR;
|
|
||||||
}
|
|
||||||
|
|
156
components/pthreads/semaphore.c
Normal file
156
components/pthreads/semaphore.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "semaphore.h"
|
||||||
|
|
||||||
|
int sem_close(sem_t *sem)
|
||||||
|
{
|
||||||
|
if (!sem) return EINVAL;
|
||||||
|
|
||||||
|
/* delete semaphore allocated in sem_open */
|
||||||
|
rt_sem_delete(sem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_destroy(sem_t *sem)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
if (!sem) return EINVAL;
|
||||||
|
|
||||||
|
/* check whether semaphore is busy or not */
|
||||||
|
result = rt_sem_trytake(sem);
|
||||||
|
if (result != RT_EOK) return EBUSY;
|
||||||
|
|
||||||
|
rt_memset(sem, 0, sizeof(sem_t));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_unlink(const char *name)
|
||||||
|
{
|
||||||
|
return EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_getvalue(sem_t *sem, int *sval)
|
||||||
|
{
|
||||||
|
RT_ASSERT(sem != RT_NULL);
|
||||||
|
if (sval) *sval = sem->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
char name[RT_NAME_MAX];
|
||||||
|
static rt_uint16_t psem_number = 0;
|
||||||
|
|
||||||
|
RT_ASSERT(sem != RT_NULL);
|
||||||
|
|
||||||
|
rt_snprintf(name, sizeof(name), "psem%02d", psem_number++);
|
||||||
|
result = rt_sem_init(sem, name, value, RT_IPC_FLAG_FIFO);
|
||||||
|
if (result == RT_EOK)
|
||||||
|
{
|
||||||
|
/* detach kernel object */
|
||||||
|
rt_object_detach(&(sem->parent.parent));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* introduce from kservice.c */
|
||||||
|
#define rt_list_entry(node, type, member) \
|
||||||
|
((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
|
||||||
|
|
||||||
|
sem_t *sem_open(const char *name, int oflag, ...)
|
||||||
|
{
|
||||||
|
rt_sem_t sem;
|
||||||
|
|
||||||
|
sem = RT_NULL;
|
||||||
|
if (oflag == O_CREAT)
|
||||||
|
{
|
||||||
|
sem = rt_sem_create(name, 1, RT_IPC_FLAG_FIFO);
|
||||||
|
if (sem == RT_NULL)
|
||||||
|
rt_set_errno(ENOSPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find semaphore */
|
||||||
|
if (oflag == O_EXCL)
|
||||||
|
{
|
||||||
|
struct rt_object* object;
|
||||||
|
struct rt_list_node* node;
|
||||||
|
struct rt_object_information *information;
|
||||||
|
extern struct rt_object_information rt_object_container[];
|
||||||
|
|
||||||
|
/* enter critical */
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
/* try to find device object */
|
||||||
|
information = &rt_object_container[RT_Object_Class_Semaphore];
|
||||||
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
|
{
|
||||||
|
object = rt_list_entry(node, struct rt_object, list);
|
||||||
|
if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
|
||||||
|
{
|
||||||
|
/* leave critical */
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
return (rt_sem_t)object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* leave critical */
|
||||||
|
rt_exit_critical();
|
||||||
|
rt_set_errno(ENOENT);
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sem;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_post(sem_t *sem)
|
||||||
|
{
|
||||||
|
rt_sem_release(sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
rt_int32_t tick;
|
||||||
|
|
||||||
|
if (!sem || !abs_timeout) return EINVAL;
|
||||||
|
|
||||||
|
/* calculate os tick */
|
||||||
|
tick = abs_timeout->tv_sec/RT_TICK_PER_SECOND + (abs_timeout->tv_nsec/1000) * (1000/RT_TICK_PER_SECOND);
|
||||||
|
|
||||||
|
result = rt_sem_take(sem, tick);
|
||||||
|
if (result == -RT_ETIMEOUT) return ETIMEDOUT;
|
||||||
|
if (result == RT_EOK) return 0;
|
||||||
|
|
||||||
|
return EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_trywait(sem_t *sem)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
if (!sem) return EINVAL;
|
||||||
|
|
||||||
|
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
|
if (result == -RT_ETIMEOUT) return EAGAIN;
|
||||||
|
if (result == RT_EOK) return 0;
|
||||||
|
|
||||||
|
return EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_wait(sem_t *sem)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
result = rt_sem_take(sem, RT_WAITING_FOREVER);
|
||||||
|
if (result == RT_EOK) return 0;
|
||||||
|
|
||||||
|
return EINTR;
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user