manually merged with ARM version
This commit is contained in:
309
x502api-1.1.34/lib/osspec/osspec.c
Normal file
309
x502api-1.1.34/lib/osspec/osspec.c
Normal file
@ -0,0 +1,309 @@
|
||||
/***************************************************************************//**
|
||||
@file osspec.c
|
||||
Файл содержит некоторые внутренние функции, которые скрывают вызовы ОС:
|
||||
функции работы с объектами синхронизации, потоками и т.д.
|
||||
|
||||
@author Borisov Alexey <borisov@lcard.ru>
|
||||
@date 28.05.2012
|
||||
***************************************************************************/
|
||||
#include "osspec.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
static void f_get_abs_time(uint32_t timeout, struct timespec *timeToWait) {
|
||||
#ifdef NO_CLOCKGETTIME
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
timeToWait->tv_sec = tv.tv_sec;
|
||||
timeToWait->tv_nsec = tv.tv_usec * 1000;
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, timeToWait);
|
||||
#endif
|
||||
timeToWait->tv_sec += timeout/1000;
|
||||
timeToWait->tv_nsec += 1000000*(timeout%1000) + 1;
|
||||
while (timeToWait->tv_nsec >= 1000000000) {
|
||||
timeToWait->tv_sec++;
|
||||
timeToWait->tv_nsec -=1000000000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OSSPEC_USE_MUTEX
|
||||
/***************************************************************************
|
||||
Вспомогательная функции для работы с мьютексами....
|
||||
**************************************************************************/
|
||||
//создание мьютекса
|
||||
t_mutex osspec_mutex_create(void) {
|
||||
t_mutex hnd;
|
||||
#ifdef _WIN32
|
||||
hnd = CreateMutex(NULL, FALSE, NULL);
|
||||
#else
|
||||
hnd = (t_mutex)malloc(sizeof(pthread_mutex_t));
|
||||
if (hnd!=NULL) {
|
||||
int err = pthread_mutex_init(hnd, NULL);
|
||||
if (err) {
|
||||
free(hnd);
|
||||
hnd = OSSPEC_INVALID_MUTEX;
|
||||
}
|
||||
} else {
|
||||
hnd = OSSPEC_INVALID_MUTEX;
|
||||
}
|
||||
#endif
|
||||
return hnd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//захват мьютекса
|
||||
int32_t osspec_mutex_lock(t_mutex handle, uint32_t timeout) {
|
||||
int32_t err = 0;
|
||||
if (handle == OSSPEC_INVALID_MUTEX)
|
||||
err = OSSPEC_ERR_MUTEX_INVALID_HANDLE;
|
||||
#ifdef _WIN32
|
||||
if (!err) {
|
||||
err = WaitForSingleObject(handle, timeout)==WAIT_OBJECT_0 ? 0 : OSSPEC_ERR_MUTEX_LOCK_TOUT;
|
||||
}
|
||||
#else
|
||||
if (!err) {
|
||||
int wt_res;
|
||||
#ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
|
||||
if (timeout == OSSPEC_TIMEOUT_INFINITY) {
|
||||
wt_res = pthread_mutex_lock(handle);
|
||||
} else {
|
||||
struct timespec timeToWait;
|
||||
f_get_abs_time(timeout, &timeToWait);
|
||||
wt_res = pthread_mutex_timedlock(handle, &timeToWait);
|
||||
}
|
||||
#else // HAVE_PTHREAD_MUTEX_TIMEDLOCK
|
||||
(void)timeout;
|
||||
wt_res = pthread_mutex_lock(handle);
|
||||
#endif // HAVE_PTHREAD_MUTEX_TIMEDLOCK
|
||||
if (wt_res == ETIMEDOUT) {
|
||||
err = OSSPEC_ERR_MUTEX_LOCK_TOUT;
|
||||
} else if (wt_res != 0) {
|
||||
err = OSSPEC_ERR_MUTEX_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
//освобождение мьютекса
|
||||
int32_t osspec_mutex_release(t_mutex handle) {
|
||||
int32_t res = 0;
|
||||
if (handle == OSSPEC_INVALID_MUTEX)
|
||||
res = OSSPEC_ERR_MUTEX_INVALID_HANDLE;
|
||||
#ifdef _WIN32
|
||||
if (!res)
|
||||
res = ReleaseMutex(handle) ? 0 : OSSPEC_ERR_MUTEX_RELEASE;
|
||||
#else
|
||||
if (!res && pthread_mutex_unlock(handle))
|
||||
res = OSSPEC_ERR_MUTEX_RELEASE;
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t osspec_mutex_destroy(t_mutex handle) {
|
||||
int32_t res = (handle != OSSPEC_INVALID_MUTEX) ?
|
||||
0 : OSSPEC_ERR_MUTEX_INVALID_HANDLE;
|
||||
#ifdef _WIN32
|
||||
if (!res)
|
||||
CloseHandle(handle);
|
||||
#else
|
||||
if (!res) {
|
||||
pthread_mutex_destroy(handle);
|
||||
free(handle);
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef OSSPEC_USE_EVENTS
|
||||
#ifdef _WIN32
|
||||
|
||||
#else
|
||||
struct st_osspec_event {
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
int flags;
|
||||
int val;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
t_event osspec_event_create(int32_t flags) {
|
||||
t_event evt;
|
||||
#ifdef _WIN32
|
||||
evt = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
#else
|
||||
evt = malloc(sizeof(struct st_osspec_event));
|
||||
if (evt!=NULL) {
|
||||
if (pthread_mutex_init(&evt->mutex, NULL) != 0) {
|
||||
free(evt);
|
||||
evt = NULL;
|
||||
} else {
|
||||
if (pthread_cond_init(&evt->cond, NULL)!= 0) {
|
||||
pthread_mutex_destroy(&evt->mutex);
|
||||
free(evt);
|
||||
evt = NULL;
|
||||
} else {
|
||||
evt->flags = flags;
|
||||
evt->val = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return evt;
|
||||
}
|
||||
|
||||
int32_t osspec_event_destroy(t_event event) {
|
||||
int32_t res = (event != OSSPEC_INVALID_EVENT) ?
|
||||
0 : OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
#ifdef _WIN32
|
||||
if (!res)
|
||||
CloseHandle(event);
|
||||
#else
|
||||
if (!res) {
|
||||
pthread_mutex_destroy(&event->mutex);
|
||||
pthread_cond_destroy(&event->cond);
|
||||
free(event);
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t osspec_event_set(t_event event) {
|
||||
int32_t res = (event != OSSPEC_INVALID_EVENT) ?
|
||||
0 : OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
if (res == 0) {
|
||||
#ifdef _WIN32
|
||||
if (!SetEvent(event))
|
||||
res = OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
#else
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
if (!event->val) {
|
||||
event->val = 1;
|
||||
pthread_cond_signal(&event->cond);
|
||||
}
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
int32_t osspec_event_clear(t_event event) {
|
||||
int32_t res = (event != OSSPEC_INVALID_EVENT) ?
|
||||
0 : OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
if (res == 0) {
|
||||
#ifdef _WIN32
|
||||
if (!ResetEvent(event))
|
||||
res = OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
#else
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->val = 0;
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t osspec_event_wait(t_event event, uint32_t timeout) {
|
||||
int32_t err = (event != OSSPEC_INVALID_EVENT) ?
|
||||
0 : OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
if (err == 0) {
|
||||
#ifdef _WIN32
|
||||
err = WaitForSingleObject(event, timeout)==WAIT_OBJECT_0 ? 0 : OSSPEC_ERR_EVENT_WAIT_TOUT;
|
||||
#else
|
||||
struct timespec timeToWait;
|
||||
int out = 0;
|
||||
if (timeout != OSSPEC_TIMEOUT_INFINITY)
|
||||
f_get_abs_time(timeout, &timeToWait);
|
||||
|
||||
while (!out && !err) {
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
if (!event->val) {
|
||||
int wait_res = timeout == OSSPEC_TIMEOUT_INFINITY ?
|
||||
pthread_cond_wait(&event->cond,&event->mutex) :
|
||||
pthread_cond_timedwait(&event->cond,&event->mutex, &timeToWait);
|
||||
if (event->val) {
|
||||
out = 1;
|
||||
} else if (wait_res == ETIMEDOUT) {
|
||||
err = OSSPEC_ERR_EVENT_WAIT_TOUT;
|
||||
} else if (wait_res == EINVAL) {
|
||||
err = OSSPEC_ERR_EVENT_INVALID_HANDLE;
|
||||
}
|
||||
} else {
|
||||
out = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSSPEC_USE_THREADS
|
||||
t_thread osspec_thread_create(t_osspec_thread_func func, void *arg, uint32_t flags) {
|
||||
t_thread thread;
|
||||
#ifdef _WIN32
|
||||
thread = CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||
#else
|
||||
if (pthread_create(&thread, NULL, func, arg) != 0) {
|
||||
thread = OSSPEC_INVALID_THREAD;
|
||||
}
|
||||
#endif
|
||||
return thread;
|
||||
}
|
||||
|
||||
int32_t osspec_thread_wait(t_thread thread, uint32_t timeout) {
|
||||
int32_t err = (thread != OSSPEC_INVALID_THREAD) ?
|
||||
0 : OSSPEC_ERR_THREAD_INVALID_HANDLE;
|
||||
if (!err) {
|
||||
#ifdef _WIN32
|
||||
err = WaitForSingleObject(thread, timeout)==WAIT_OBJECT_0 ? 0 : OSSPEC_ERR_THREAD_WAIT_TOUT;
|
||||
#else
|
||||
int wt_res;
|
||||
|
||||
#ifndef OSSPEC_THREAD_NO_TIMEOUT
|
||||
if (timeout != OSSPEC_TIMEOUT_INFINITY) {
|
||||
struct timespec timeToWait;
|
||||
f_get_abs_time(timeout, &timeToWait);
|
||||
wt_res = pthread_timedjoin_np(thread, NULL, &timeToWait);
|
||||
} else {
|
||||
#endif
|
||||
wt_res = pthread_join(thread, NULL);
|
||||
#ifndef OSSPEC_THREAD_NO_TIMEOUT
|
||||
}
|
||||
#endif
|
||||
if (wt_res == ETIMEDOUT) {
|
||||
err = OSSPEC_ERR_THREAD_WAIT_TOUT;
|
||||
} else if (wt_res != 0) {
|
||||
err = OSSPEC_ERR_THREAD_INVALID_HANDLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user