869 |
|
// Linux select() changes its timeout parameter upon return to contain |
870 |
|
// the remaining time. Most other unixen leave it unchanged or undefined. |
871 |
|
#define SELECT_SETS_REMAINING |
872 |
< |
#elif defined(__FreeBSD__) || defined(__sun__) || defined(sgi) |
872 |
> |
#elif defined(__FreeBSD__) || defined(__sun__) |
873 |
|
#define USE_NANOSLEEP |
874 |
+ |
#elif defined(HAVE_PTHREADS) && defined(sgi) |
875 |
+ |
// SGI pthreads has a bug when using pthreads+signals+nanosleep, |
876 |
+ |
// so instead of using nanosleep, wait on a CV which is never signalled. |
877 |
+ |
#define USE_COND_TIMEDWAIT |
878 |
|
#endif |
879 |
|
|
880 |
|
void Delay_usec(uint32 usec) |
881 |
|
{ |
882 |
|
int was_error; |
883 |
|
|
884 |
< |
#ifdef USE_NANOSLEEP |
884 |
> |
#if defined(USE_NANOSLEEP) |
885 |
|
struct timespec elapsed, tv; |
886 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
887 |
+ |
// Use a local mutex and cv, so threads remain independent |
888 |
+ |
pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER; |
889 |
+ |
pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER; |
890 |
+ |
struct timespec elapsed; |
891 |
+ |
uint64 future; |
892 |
|
#else |
893 |
|
struct timeval tv; |
894 |
|
#ifndef SELECT_SETS_REMAINING |
897 |
|
#endif |
898 |
|
|
899 |
|
// Set the timeout interval - Linux only needs to do this once |
900 |
< |
#ifdef SELECT_SETS_REMAINING |
900 |
> |
#if defined(SELECT_SETS_REMAINING) |
901 |
|
tv.tv_sec = 0; |
902 |
|
tv.tv_usec = usec; |
903 |
|
#elif defined(USE_NANOSLEEP) |
904 |
|
elapsed.tv_sec = 0; |
905 |
|
elapsed.tv_nsec = usec * 1000; |
906 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
907 |
+ |
future = GetTicks_usec() + usec; |
908 |
+ |
elapsed.tv_sec = future / 1000000; |
909 |
+ |
elapsed.tv_nsec = (future % 1000000) * 1000; |
910 |
|
#else |
911 |
|
then = GetTicks_usec(); |
912 |
|
#endif |
913 |
|
|
914 |
|
do { |
915 |
|
errno = 0; |
916 |
< |
#ifdef USE_NANOSLEEP |
916 |
> |
#if defined(USE_NANOSLEEP) |
917 |
|
tv.tv_sec = elapsed.tv_sec; |
918 |
|
tv.tv_nsec = elapsed.tv_nsec; |
919 |
|
was_error = nanosleep(&tv, &elapsed); |
920 |
+ |
#elif defined(USE_COND_TIMEDWAIT) |
921 |
+ |
was_error = pthread_mutex_lock(&delay_mutex); |
922 |
+ |
was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed); |
923 |
+ |
was_error = pthread_mutex_unlock(&delay_mutex); |
924 |
|
#else |
925 |
|
#ifndef SELECT_SETS_REMAINING |
926 |
|
// Calculate the time interval left (in case of interrupt) |