diff --git a/qse/include/qse/cmn/time.h b/qse/include/qse/cmn/time.h index ee37ddde..8be0377b 100644 --- a/qse/include/qse/cmn/time.h +++ b/qse/include/qse/cmn/time.h @@ -75,6 +75,9 @@ #define QSE_SECNSEC_TO_MSEC(sec,nsec) \ (((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_MSEC_TO_SEC(sec) ((sec) / QSE_MSECS_PER_SEC) diff --git a/qse/include/qse/sys/mtx.h b/qse/include/qse/sys/mtx.h index 9cf6eb2b..b254246b 100644 --- a/qse/include/qse/sys/mtx.h +++ b/qse/include/qse/sys/mtx.h @@ -30,6 +30,7 @@ #include #include +#include typedef struct qse_mtx_t qse_mtx_t; @@ -39,14 +40,19 @@ typedef struct qse_mtx_t qse_mtx_t; #elif defined(__OS2__) - /* not implemented */ -# error not implemented + /* typdef unsigned long ULONG; + * typedef ULONG HMTX; */ + typedef unsigned long qse_mtx_hnd_t; + #elif defined(__DOS__) /* not implemented */ # error not implemented + #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; + #else # if (QSE_SIZEOF_PTHREAD_MUTEX_T == 0) @@ -113,16 +119,14 @@ void* qse_mtx_getxtn ( ); int qse_mtx_lock ( - qse_mtx_t* mtx + qse_mtx_t* mtx, + qse_ntime_t* waiting_time ); int qse_mtx_unlock ( - qse_mtx_t* mtx + qse_mtx_t* mtx ); -int qse_mtx_trylock ( - qse_mtx_t* mtx -); #ifdef __cplusplus } diff --git a/qse/lib/sys/cnd.c b/qse/lib/sys/cnd.c index aff905e2..003e53dc 100644 --- a/qse/lib/sys/cnd.c +++ b/qse/lib/sys/cnd.c @@ -30,6 +30,7 @@ #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if defined(_WIN32) + #include #include #elif defined(__OS2__) /* 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)); cnd->mmgr = mmgr; -#ifdef _WIN32 +#if defined(_WIN32) cnd->gone = 0; cnd->blocked = 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->mutex == QSE_NULL) { - int num = qse_maperrno (GetLastError()); - if (cnd->gate) CloseHandle (cnd->gate); if (cnd->queue) CloseHandle (cnd->queue); 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) { -#ifdef _WIN32 +#if defined(_WIN32) CloseHandle (cnd->gate); CloseHandle (cnd->queue); CloseHandle (cnd->mutex); @@ -122,7 +121,7 @@ void qse_cnd_fini (qse_cnd_t* cnd) void qse_cnd_signal (qse_cnd_t* cnd) { -#ifdef _WIN32 +#if defined(_WIN32) unsigned int signals = 0; 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) { -#ifdef _WIN32 +#if defined(_WIN32) unsigned int signals = 0; 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) { -#ifdef _WIN32 +#if defined(_WIN32) unsigned int was_waiting, was_gone; 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) { - 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 { @@ -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); } - qse_mtx_lock (mutex); + qse_mtx_lock (mutex, QSE_NULL); #else 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 } -#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 diff --git a/qse/lib/sys/mtx.c b/qse/lib/sys/mtx.c index 9196cfdf..f2b202f4 100644 --- a/qse/lib/sys/mtx.c +++ b/qse/lib/sys/mtx.c @@ -30,19 +30,25 @@ #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if defined(_WIN32) - #include +# include +# include #elif defined(__OS2__) - /* implement this */ + +# define INCL_DOSSEMAPHORES +# include + #elif defined(__DOS__) /* implement this */ + #elif defined(__BEOS__) - #include +# include + #else - #if defined(AIX) && defined(__GNUC__) +# if defined(AIX) && defined(__GNUC__) typedef int crid_t; typedef unsigned int class_id_t; - #endif - #include +# endif +# include #endif qse_mtx_t* qse_mtx_open (qse_mmgr_t* mmgr, qse_size_t xtnsize) @@ -79,7 +85,17 @@ int qse_mtx_init (qse_mtx_t* mtx, qse_mmgr_t* mmgr) if (mtx->hnd == QSE_NULL) return -1; #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__) # error not implemented @@ -114,7 +130,7 @@ void qse_mtx_fini (qse_mtx_t* mtx) CloseHandle (mtx->hnd); #elif defined(__OS2__) -# error not implemented + DosCloseMutexSem (mtx->hnd); #elif defined(__DOS__) # error not implemented @@ -138,7 +154,7 @@ void* qse_mtx_getxtn (qse_mtx_t* 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) /* @@ -153,15 +169,61 @@ int qse_mtx_lock (qse_mtx_t* mtx) * state is nonsignaled. * WAIT_FAILED An error occurred */ - if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED) + if (waiting_time) { - qse_seterrno (qse_maperrno(GetLastError())); - return -1; + DWORD msec; + 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__) - if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1; + 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; + } #else - if (pthread_mutex_lock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1; + + 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; + } #endif return 0; } @@ -170,28 +232,21 @@ int qse_mtx_unlock (qse_mtx_t* mtx) { #if defined(_WIN32) 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__) if (release_sem(mtx->hnd) != B_NO_ERROR) return -1; + #else if (pthread_mutex_unlock ((pthread_mutex_t*)&mtx->hnd) != 0) return -1; #endif 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 diff --git a/qse/lib/sys/thr.h b/qse/lib/sys/thr.h index ba99a6f1..c875dd23 100644 --- a/qse/lib/sys/thr.h +++ b/qse/lib/sys/thr.h @@ -33,6 +33,7 @@ #if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) #if defined(_WIN32) +# include # include # define QSE_THR_HND_INVALID INVALID_HANDLE_VALUE #elif defined(__OS2__)