manually merged with ARM version
This commit is contained in:
25
x502api-1.1.34/lib/osspec/_osspec_cfg.h
Normal file
25
x502api-1.1.34/lib/osspec/_osspec_cfg.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef OS_SPEC_CFG_H_
|
||||
#define OS_SPEC_CFG_H_
|
||||
|
||||
|
||||
//#define OSSPEC_USE_MUTEX
|
||||
//#define OSSPEC_USE_EVENTS
|
||||
//#define OSSPEC_USE_THREADS
|
||||
|
||||
|
||||
#define OSSPEC_ERR_MUTEX_INVALID_HANDLE -1
|
||||
#define OSSPEC_ERR_MUTEX_LOCK_TOUT -2
|
||||
#define OSSPEC_ERR_MUTEX_RELEASE -3
|
||||
|
||||
|
||||
#define OSSPEC_ERR_EVENT_INVALID_HANDLE OSSPEC_ERR_MUTEX_INVALID_HANDLE
|
||||
#define OSSPEC_ERR_EVENT_WAIT_TOUT OSSPEC_ERR_MUTEX_LOCK_TOUT
|
||||
|
||||
|
||||
#define OSSPEC_ERR_THREAD_INVALID_HANDLE OSSPEC_ERR_MUTEX_INVALID_HANDLE
|
||||
#define OSSPEC_ERR_THREAD_WAIT_TOUT OSSPEC_ERR_MUTEX_LOCK_TOUT
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
59
x502api-1.1.34/lib/osspec/osspec.cmake
Normal file
59
x502api-1.1.34/lib/osspec/osspec.cmake
Normal file
@ -0,0 +1,59 @@
|
||||
# Файл для включения в проект на CMAKE.
|
||||
# Перед включением необходимо определить переменные
|
||||
# OSSPEC_DIR - путь к директории, где находится osspec.cmake
|
||||
# OSSPEC_USE_EVENTS - использовать события
|
||||
# OSSPEC_USE_THREADS - использовать потоки
|
||||
# OSSPEC_USE_MUTEX - использовать мьютексы
|
||||
# После включения будут установлены следующие перменные:
|
||||
# OSSPEC_HEADERS - используемые заголовочные файлы
|
||||
# OSSPEC_SOURCES - используемые файлы исходных кодов
|
||||
# OSSPEC_DEFINITIONS - используемые определения компилятора
|
||||
cmake_policy(PUSH)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
|
||||
if(OSSPEC_USE_EVENTS OR OSSPEC_USE_THREADS OR OSSPEC_USE_MUTEX)
|
||||
find_package(Threads)
|
||||
# set(OSSPEC_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
unset(OSSPEC_LIBS)
|
||||
unset(OSSPEC_DEFINITIONS)
|
||||
set(OSSPEC_HEADERS ${OSSPEC_DIR}/osspec.h)
|
||||
set(OSSPEC_SOURCES ${OSSPEC_DIR}/osspec.c)
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
include(CheckLibraryExists)
|
||||
if(OSSPEC_USE_MUTEX)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} OSSPEC_USE_MUTEX)
|
||||
check_library_exists(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
||||
if(HAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} HAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
||||
#заглушки для _timedlock функций отстутсвуют в libc, поэтому в любом случае включаем pthread
|
||||
set(OSSPEC_LIBS ${OSSPEC_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif(HAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
||||
endif(OSSPEC_USE_MUTEX)
|
||||
|
||||
if(OSSPEC_USE_THREADS)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} OSSPEC_USE_THREADS)
|
||||
if (NOT OSSPEC_LIBS)
|
||||
set(OSSPEC_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif (NOT OSSPEC_LIBS)
|
||||
check_library_exists(pthread pthread_timedjoin_np "" HAVE_PTHREAD_TIMEDJOIN_NP)
|
||||
if(HAVE_PTHREAD_TIMEDJOIN_NP)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} HAVE_PTHREAD_TIMEDJOIN_NP)
|
||||
endif(HAVE_PTHREAD_TIMEDJOIN_NP)
|
||||
endif(OSSPEC_USE_THREADS)
|
||||
else(CMAKE_USE_PTHREADS_INIT)
|
||||
if(OSSPEC_USE_MUTEX)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} OSSPEC_USE_MUTEX)
|
||||
endif(OSSPEC_USE_MUTEX)
|
||||
if(OSSPEC_USE_THREADS)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} OSSPEC_USE_THREADS)
|
||||
endif(OSSPEC_USE_THREADS)
|
||||
endif(CMAKE_USE_PTHREADS_INIT)
|
||||
|
||||
if(OSSPEC_USE_EVENTS)
|
||||
set(OSSPEC_DEFINITIONS ${OSSPEC_DEFINITIONS} OSSPEC_USE_EVENTS)
|
||||
endif(OSSPEC_USE_EVENTS)
|
||||
endif(OSSPEC_USE_EVENTS OR OSSPEC_USE_THREADS OR OSSPEC_USE_MUTEX)
|
||||
|
||||
cmake_policy(POP)
|
||||
93
x502api-1.1.34/lib/osspec/osspec.h
Normal file
93
x502api-1.1.34/lib/osspec/osspec.h
Normal file
@ -0,0 +1,93 @@
|
||||
/***************************************************************************//**
|
||||
@file osspec.h
|
||||
Файл содержит объявления функций, которые скрывают вызовы ОС:
|
||||
функции работы с объектами синхронизации, потоками и т.д.
|
||||
|
||||
@author Borisov Alexey <borisov@lcard.ru>
|
||||
@date 28.05.2012
|
||||
***************************************************************************/
|
||||
#ifndef OSSPEC_H_
|
||||
#define OSSPEC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined _WIN32 && !defined _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "osspec_cfg.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#define OSSPEC_TIMEOUT_INFINITY INFINITE
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define OSSPEC_TIMEOUT_INFINITY ((uint32_t)-1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_OSSPEC_USE_MUTEX
|
||||
#ifdef _WIN32
|
||||
typedef HANDLE t_mutex;
|
||||
#else
|
||||
typedef pthread_mutex_t* t_mutex;
|
||||
#endif
|
||||
|
||||
#define OSSPEC_INVALID_MUTEX NULL
|
||||
|
||||
t_mutex osspec_mutex_create(void);
|
||||
int32_t osspec_mutex_lock(t_mutex handle, uint32_t tout);
|
||||
int32_t osspec_mutex_release(t_mutex handle);
|
||||
int32_t osspec_mutex_destroy(t_mutex handle);
|
||||
#endif
|
||||
|
||||
#ifndef NO_OSSPEC_USE_EVENTS
|
||||
#ifdef _WIN32
|
||||
typedef HANDLE t_event;
|
||||
#else
|
||||
struct st_osspec_event;
|
||||
typedef struct st_osspec_event *t_event;
|
||||
#endif
|
||||
|
||||
#define OSSPEC_INVALID_EVENT NULL
|
||||
|
||||
t_event osspec_event_create(int32_t flags);
|
||||
int32_t osspec_event_destroy(t_event event);
|
||||
int32_t osspec_event_set(t_event event);
|
||||
int32_t osspec_event_clear(t_event event);
|
||||
int32_t osspec_event_wait(t_event event, uint32_t timeout);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_OSSPEC_USE_THREADS
|
||||
#ifdef _WIN32
|
||||
typedef HANDLE t_thread;
|
||||
|
||||
#define OSSPEC_INVALID_THREAD NULL
|
||||
|
||||
#define OSSPEC_THREAD_FUNC_RET DWORD
|
||||
#define OSSPEC_THREAD_FUNC_CALL WINAPI
|
||||
#else
|
||||
typedef pthread_t t_thread;
|
||||
|
||||
#define OSSPEC_INVALID_THREAD ((pthread_t)-1)
|
||||
|
||||
#define OSSPEC_THREAD_FUNC_RET void*
|
||||
#define OSSPEC_THREAD_FUNC_CALL
|
||||
#endif
|
||||
|
||||
typedef OSSPEC_THREAD_FUNC_RET (OSSPEC_THREAD_FUNC_CALL *t_osspec_thread_func)(void *arg);
|
||||
|
||||
t_thread osspec_thread_create(t_osspec_thread_func func, void *arg, uint32_t flags);
|
||||
int32_t osspec_thread_wait(t_thread thread, uint32_t timeout);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user