added QSE_SECNSEC_TO_USEC()

removed qse_mtx_trylock() and added the waiting_time parameter to qse_mtx_lock()
This commit is contained in:
hyung-hwan 2015-09-30 13:22:40 +00:00
parent 74ab14974b
commit 49f4c3087f
5 changed files with 112 additions and 125 deletions

View File

@ -75,6 +75,9 @@
#define QSE_SECNSEC_TO_MSEC(sec,nsec) \ #define QSE_SECNSEC_TO_MSEC(sec,nsec) \
(((qse_long_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_MSEC)) (((qse_long_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_MSEC))
#define QSE_SECNSEC_TO_USEC(sec,nsec) \
(((qse_long_t)(sec) * QSE_USECS_PER_SEC) + ((qse_long_t)(nsec) / QSE_NSECS_PER_USEC))
#define QSE_SEC_TO_MSEC(sec) ((sec) * QSE_MSECS_PER_SEC) #define QSE_SEC_TO_MSEC(sec) ((sec) * QSE_MSECS_PER_SEC)
#define QSE_MSEC_TO_SEC(sec) ((sec) / QSE_MSECS_PER_SEC) #define QSE_MSEC_TO_SEC(sec) ((sec) / QSE_MSECS_PER_SEC)

View File

@ -30,6 +30,7 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
#include <qse/cmn/time.h>
typedef struct qse_mtx_t qse_mtx_t; typedef struct qse_mtx_t qse_mtx_t;
@ -39,14 +40,19 @@ typedef struct qse_mtx_t qse_mtx_t;
#elif defined(__OS2__) #elif defined(__OS2__)
/* not implemented */ /* typdef unsigned long ULONG;
# error not implemented * typedef ULONG HMTX; */
typedef unsigned long qse_mtx_hnd_t;
#elif defined(__DOS__) #elif defined(__DOS__)
/* not implemented */ /* not implemented */
# error not implemented # error not implemented
#elif defined(__BEOS__) #elif defined(__BEOS__)
/* typedef sem_id qse_mtx_hnd_t; */ /* typedef int32 sem_id;
* typedef sem_id qse_mtx_hnd_t; */
typdef qse_int32_t qse_mtx_hnd_t; typdef qse_int32_t qse_mtx_hnd_t;
#else #else
# if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0) # if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0)
@ -113,16 +119,14 @@ void* qse_mtx_getxtn (
); );
int qse_mtx_lock ( int qse_mtx_lock (
qse_mtx_t* mtx qse_mtx_t* mtx,
qse_ntime_t* waiting_time
); );
int qse_mtx_unlock ( int qse_mtx_unlock (
qse_mtx_t* mtx qse_mtx_t* mtx
); );
int qse_mtx_trylock (
qse_mtx_t* mtx
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -30,6 +30,7 @@
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h>
#include <process.h> #include <process.h>
#elif defined(__OS2__) #elif defined(__OS2__)
/* implement this */ /* implement this */
@ -73,7 +74,7 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
QSE_MEMSET (cnd, 0, QSE_SIZEOF(*cnd)); QSE_MEMSET (cnd, 0, QSE_SIZEOF(*cnd));
cnd->mmgr = mmgr; cnd->mmgr = mmgr;
#ifdef _WIN32 #if defined(_WIN32)
cnd->gone = 0; cnd->gone = 0;
cnd->blocked = 0; cnd->blocked = 0;
cnd->waiting = 0; cnd->waiting = 0;
@ -86,8 +87,6 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
cnd->queue == QSE_NULL || cnd->queue == QSE_NULL ||
cnd->mutex == QSE_NULL) cnd->mutex == QSE_NULL)
{ {
int num = qse_maperrno (GetLastError());
if (cnd->gate) CloseHandle (cnd->gate); if (cnd->gate) CloseHandle (cnd->gate);
if (cnd->queue) CloseHandle (cnd->queue); if (cnd->queue) CloseHandle (cnd->queue);
if (cnd->mutex) CloseHandle (cnd->mutex); if (cnd->mutex) CloseHandle (cnd->mutex);
@ -107,7 +106,7 @@ int qse_cnd_init (qse_cnd_t* cnd, qse_mmgr_t* mmgr)
void qse_cnd_fini (qse_cnd_t* cnd) void qse_cnd_fini (qse_cnd_t* cnd)
{ {
#ifdef _WIN32 #if defined(_WIN32)
CloseHandle (cnd->gate); CloseHandle (cnd->gate);
CloseHandle (cnd->queue); CloseHandle (cnd->queue);
CloseHandle (cnd->mutex); CloseHandle (cnd->mutex);
@ -122,7 +121,7 @@ void qse_cnd_fini (qse_cnd_t* cnd)
void qse_cnd_signal (qse_cnd_t* cnd) void qse_cnd_signal (qse_cnd_t* cnd)
{ {
#ifdef _WIN32 #if defined(_WIN32)
unsigned int signals = 0; unsigned int signals = 0;
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE); WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
@ -166,7 +165,7 @@ void qse_cnd_signal (qse_cnd_t* cnd)
void qse_cnd_broadcast (qse_cnd_t* cnd) void qse_cnd_broadcast (qse_cnd_t* cnd)
{ {
#ifdef _WIN32 #if defined(_WIN32)
unsigned int signals = 0; unsigned int signals = 0;
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE); WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
@ -210,7 +209,7 @@ void qse_cnd_broadcast (qse_cnd_t* cnd)
void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time) void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
{ {
#ifdef _WIN32 #if defined(_WIN32)
unsigned int was_waiting, was_gone; unsigned int was_waiting, was_gone;
int signaled; int signaled;
@ -222,7 +221,10 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
if (waiting_time) if (waiting_time)
{ {
signaled = (WaitForSingleObject((HANDLE)cnd->queue, (DWORD)waiting_time) == WAIT_OBJECT_0); DWORD msec;
msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
signaled = (WaitForSingleObject((HANDLE)cnd->queue, msec) == WAIT_OBJECT_0);
} }
else else
{ {
@ -279,7 +281,7 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL); ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
} }
qse_mtx_lock (mutex); qse_mtx_lock (mutex, QSE_NULL);
#else #else
if (waiting_time) if (waiting_time)
{ {
@ -302,82 +304,4 @@ void qse_cnd_wait (qse_cnd_t* cnd, qse_mtx_t* mutex, qse_ntime_t* waiting_time)
#endif #endif
} }
#if 0
void qse_cnd_twait (
qse_cnd_t* cnd, qse_mtx_t* mutex, qse_time_t waiting_time)
{
#ifdef _WIN32
qse_bool_t signaled;
unsigned int was_waiting, was_gone;
WaitForSingleObject ((HANDLE)cnd->gate, INFINITE);
++cnd->blocked;
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
qse_mtx_unlock (mutex);
signaled = (WaitForSingleObject((HANDLE)cnd->queue, (DWORD)waiting_time) == WAIT_OBJECT_0);
was_waiting = 0;
was_gone = 0;
WaitForSingleObject ((HANDLE)cnd->mutex, INFINITE);
was_waiting = cnd->waiting;
was_gone = cnd->gone;
if (was_waiting != 0)
{
if (!signaled)
{ /* timed out */
if (cnd->blocked != 0) --(cnd->blocked);
else ++(cnd->gone);
}
if (--(cnd->waiting) == 0)
{
if (cnd->blocked != 0)
{
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
was_waiting = 0;
}
else if (cnd->gone != 0) cnd->gone = 0;
}
}
else if (++(cnd->gone) == QSE_TYPE_MAX(unsigned int) / 2)
{
WaitForSingleObject ((HANDLE)cnd->gate, INFINITE);
cnd->blocked -= cnd->gone;
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
cnd->gone = 0;
}
ReleaseMutex ((HANDLE)cnd->mutex);
if (was_waiting == 1)
{
for (;was_gone; --was_gone)
{
WaitForSingleObject ((HANDLE)cnd->queue, INFINITE);
}
ReleaseSemaphore ((HANDLE)cnd->gate, 1, QSE_NULL);
}
qse_mtx_lock (mutex);
#else
qse_time_t now;
qse_timespec_t timeout;
qse_gettime (&now);
now += waiting_time;
QSE_TIME_TO_TIMESPEC (now, &timeout);
QSE_ASSERT (QSE_SIZEOF(timeout) == QSE_SIZEOF(struct timespec));
pthread_cond_timedwait (&cnd->hnd, &mutex->hnd, &timeout);
#endif
}
#endif
#endif #endif

View File

@ -30,13 +30,19 @@
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
#if defined(_WIN32) #if defined(_WIN32)
# include <windows.h>
# include <process.h> # include <process.h>
#elif defined(__OS2__) #elif defined(__OS2__)
/* implement this */
# define INCL_DOSSEMAPHORES
# include <os2.h>
#elif defined(__DOS__) #elif defined(__DOS__)
/* implement this */ /* implement this */
#elif defined(__BEOS__) #elif defined(__BEOS__)
# include <be/kernel/OS.h> # include <be/kernel/OS.h>
#else #else
# if defined(AIX) && defined(__GNUC__) # if defined(AIX) && defined(__GNUC__)
typedef int crid_t; typedef int crid_t;
@ -79,7 +85,17 @@ int qse_mtx_init (qse_mtx_t* mtx, qse_mmgr_t* mmgr)
if (mtx->hnd == QSE_NULL) return -1; if (mtx->hnd == QSE_NULL) return -1;
#elif defined(__OS2__) #elif defined(__OS2__)
# error not implemented
{
APIRET rc;
HMTX m;
rc = DosCreateMutexSem (QSE_NULL, &m, DC_SEM_SHARED, FALSE);
if (rc != NO_ERROR) return -1;
mtx->hnd = m;
return 0;
}
#elif defined(__DOS__) #elif defined(__DOS__)
# error not implemented # error not implemented
@ -114,7 +130,7 @@ void qse_mtx_fini (qse_mtx_t* mtx)
CloseHandle (mtx->hnd); CloseHandle (mtx->hnd);
#elif defined(__OS2__) #elif defined(__OS2__)
# error not implemented DosCloseMutexSem (mtx->hnd);
#elif defined(__DOS__) #elif defined(__DOS__)
# error not implemented # error not implemented
@ -138,7 +154,7 @@ void* qse_mtx_getxtn (qse_mtx_t* mtx)
return QSE_XTN (mtx); return QSE_XTN (mtx);
} }
int qse_mtx_lock (qse_mtx_t* mtx) int qse_mtx_lock (qse_mtx_t* mtx, qse_ntime_t* waiting_time)
{ {
#if defined(_WIN32) #if defined(_WIN32)
/* /*
@ -153,15 +169,61 @@ int qse_mtx_lock (qse_mtx_t* mtx)
* state is nonsignaled. * state is nonsignaled.
* WAIT_FAILED An error occurred * WAIT_FAILED An error occurred
*/ */
if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED) if (waiting_time)
{ {
qse_seterrno (qse_maperrno(GetLastError())); DWORD msec;
return -1; msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
if (WaitForSingleObject(mtx->hnd, msec) != WAIT_OBJECT_0) return -1;
} }
else
{
if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED) return -1;
}
#elif defined(__OS2__)
if (waiting_time)
{
ULONG msec;
msec = QSE_SECNSEC_TO_MSEC (waiting_time->sec, waiting_time->nsec);
if (DosRequestMutexSem (mtx->hnd, msec) != NO_ERROR) return -1;
}
else
{
if (DosRequestMutexSem (mtx->hnd, SEM_INDEFINITE_WAIT) != NO_ERROR) return -1;
}
#elif defined(__DOS__)
/* nothing to do */
#elif defined(__BEOS__) #elif defined(__BEOS__)
if (waiting_time)
{
/* TODO: check for B_WOULD_BLOCK */
/*if (acquire_sem_etc(mtx->hnd, 1, B_ABSOLUTE_TIMEOUT, 0) != B_NO_ERROR) return -1;*/
bigtime_t usec;
usec = QSE_SECNSEC_TO_USEC (waiting_time->sec, waiting_time->nsec);
if (acquire_sem_etc(mtx->hnd, 1, B_TIMEOUT, 0) != B_NO_ERROR) return -1;
}
else
{
if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1; if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1;
}
#else #else
if (waiting_time)
{
struct timespec ts;
ts.tv_sec = waiting_time->sec;
ts.tv_nsec = waiting_time->nsec;
if (pthread_mutex_timedlock ((pthread_mutex_t*)&mtx->hnd, &ts) != 0) return -1;
}
else
{
if (pthread_mutex_lock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1; if (pthread_mutex_lock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
}
#endif #endif
return 0; return 0;
} }
@ -170,28 +232,21 @@ int qse_mtx_unlock (qse_mtx_t* mtx)
{ {
#if defined(_WIN32) #if defined(_WIN32)
if (ReleaseMutex (mtx->hnd) == FALSE) return -1; if (ReleaseMutex (mtx->hnd) == FALSE) return -1;
#elif defined(__OS2__)
if (DosReleaseMutexSem (mtx->hnd) != NO_ERROR) return -1;
#elif defined(__DOS__)
/* nothing to do */
#elif defined(__BEOS__) #elif defined(__BEOS__)
if (release_sem(mtx->hnd) != B_NO_ERROR) return -1; if (release_sem(mtx->hnd) != B_NO_ERROR) return -1;
#else #else
if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1; if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
#endif #endif
return 0; return 0;
} }
int qse_mtx_trylock (qse_mtx_t* mtx)
{
#if defined(_WIN32)
if (WaitForSingleObject(mtx->hnd, 0) != WAIT_OBJECT_0) return -1;
#elif defined(__BEOS__)
if (acquire_sem_etc(mtx->hnd, 1, B_ABSOLUTE_TIMEOUT, 0) != B_NO_ERROR)
{
/* TODO: check for B_WOULD_BLOCK */
return -1;
}
#else
if (pthread_mutex_trylock((pthread_mutex_t*)&mtx->hnd) != 0) return -1;
#endif
return 0;
}
#endif #endif

View File

@ -33,6 +33,7 @@
#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD)
#if defined(_WIN32) #if defined(_WIN32)
# include <windows.h>
# include <process.h> # include <process.h>
# define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE # define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE
#elif defined(__OS2__) #elif defined(__OS2__)