int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec *ts) { rwlock_t *rwlock; int ret; pthread_testcancel(); ret = rwl_ref(rwlock_,0); if(ret != 0) return ret; rwlock = (rwlock_t *)*rwlock_; if ((ret = pthread_mutex_timedlock (&rwlock->mex, ts)) != 0) return rwl_unref(rwlock_, ret); InterlockedIncrement(&rwlock->nsh_count); if (rwlock->nsh_count == INT_MAX) { ret = pthread_mutex_timedlock(&rwlock->mcomplete, ts); if (ret != 0) { if (ret == ETIMEDOUT) InterlockedIncrement(&rwlock->ncomplete); pthread_mutex_unlock(&rwlock->mex); return rwl_unref(rwlock_, ret); } rwlock->nsh_count -= rwlock->ncomplete; rwlock->ncomplete = 0; ret = rwlock_free_both_locks(rwlock, 0); return rwl_unref(rwlock_, ret); } ret = pthread_mutex_unlock(&rwlock->mex); return rwl_unref(rwlock_, ret); }
int mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout) { pthread_t id; switch (mutex->type) { case MONO_MUTEX_NORMAL: return pthread_mutex_timedlock (&mutex->mutex, timeout); case MONO_MUTEX_RECURSIVE: id = pthread_self (); if (pthread_mutex_timedlock (&mutex->mutex, timeout) != 0) return ETIMEDOUT; while (1) { if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) { mutex->owner = id; mutex->depth = 1; break; } else if (pthread_equal (mutex->owner, id)) { mutex->depth++; break; } else { mutex->waiters++; if (pthread_cond_timedwait (&mutex->cond, &mutex->mutex, timeout) != 0) return ETIMEDOUT; mutex->waiters--; } } return pthread_mutex_unlock (&mutex->mutex); } return EINVAL; }
static int do_test (void) { struct timespec tms = { 0 }; pthread_mutex_t mutex; pthread_mutexattr_t mutexattr; int ret = 0; if (pthread_mutexattr_init (&mutexattr) != 0) return 1; if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0) return 1; if (pthread_mutex_init (&mutex, &mutexattr) != 0) return 1; if (pthread_mutexattr_destroy (&mutexattr) != 0) return 1; /* The call to pthread_mutex_timedlock erroneously enabled lock elision on the mutex, which then triggered an assertion failure in pthread_mutex_unlock. It would also defeat the error checking nature of the mutex. */ if (pthread_mutex_timedlock (&mutex, &tms) != 0) return 1; if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK) { printf ("Failed error checking on locked mutex\n"); ret = 1; } if (pthread_mutex_unlock (&mutex) != 0) ret = 1; return ret; }
/** * Obtain lock on debug lock structure. This could be a deadlock by the caller. * The debug code itself does not deadlock. Anyway, check with timeouts. * @param lock: on what to acquire lock. * @param func: user level caller identification. * @param file: user level caller identification. * @param line: user level caller identification. */ static void acquire_locklock(struct checked_lock* lock, const char* func, const char* file, int line) { struct timespec to; int err; int contend = 0; /* first try; inc contention counter if not immediately */ if((err = pthread_mutex_trylock(&lock->lock))) { if(err==EBUSY) contend++; else fatal_exit("error in mutex_trylock: %s", strerror(err)); } if(!err) return; /* immediate success */ to.tv_sec = time(NULL) + CHECK_LOCK_TIMEOUT; to.tv_nsec = 0; err = pthread_mutex_timedlock(&lock->lock, &to); if(err) { log_err("in acquiring locklock: %s", strerror(err)); lock_error(lock, func, file, line, "acquire locklock"); } /* since we hold the lock, we can edit the contention_count */ lock->contention_count += contend; }
/*----------------------------------------------------------------------------*/ bool mutexTryLock(struct Mutex *mutex, unsigned int interval) { int res; if (interval) { struct timespec timestamp; clock_gettime(CLOCK_REALTIME, ×tamp); timestamp.tv_sec += interval / 1000; timestamp.tv_nsec += (interval % 1000) * 1000000; if (timestamp.tv_nsec >= 1000000000) { timestamp.tv_nsec -= 1000000000; ++timestamp.tv_sec; } res = pthread_mutex_timedlock(mutex->handle, ×tamp); } else res = pthread_mutex_trylock(mutex->handle); return res ? false : true; }
int main(void) { int err; struct timespec tout; struct tm *tmp; char buf[64]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); printf("mutex is locked\n"); clock_gettime(CLOCK_REALTIME, &tout); tmp = localtime(&tout.tv_sec); strftime(buf, sizeof(buf), "%r", tmp); printf("current time is %s\n", buf); tout.tv_sec += 10; err = pthread_mutex_timedlock(&lock, &tout); tmp = localtime(&tout.tv_sec); strftime(buf, sizeof(buf), "%r", tmp); printf("the time is now %s\n", buf); if(err == 0) printf("mutex locked again!\n"); else printf("can not lock mvtex agin:%s\n",strerror(err)); return 0; }
int almtx_timedlock(almtx_t *mtx, const struct timespec *ts) { int ret; #ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK ret = pthread_mutex_timedlock(mtx, ts); switch(ret) { case 0: return althrd_success; case ETIMEDOUT: return althrd_timedout; case EBUSY: return althrd_busy; } return althrd_error; #else if(!mtx || !ts) return althrd_error; while((ret=almtx_trylock(mtx)) == althrd_busy) { struct timespec now; if(ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000 || altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC) return althrd_error; if(now.tv_sec > ts->tv_sec || (now.tv_sec == ts->tv_sec && now.tv_nsec >= ts->tv_nsec)) return althrd_timedout; althrd_yield(); } return ret; #endif }
/**************************** * * Thread's start routine. * f1() * * *************************/ void *f1(void *parm) { struct timespec timeout; /* Get the current time before the mutex locked. */ gettimeofday(&currsec1, NULL); /* Absolute time, not relative. */ timeout.tv_sec = currsec1.tv_sec + TIMEOUT; timeout.tv_nsec = currsec1.tv_usec * 1000; printf ("Timed mutex lock will block for %d seconds starting from: %ld.%06ld\n", TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_usec); if (pthread_mutex_timedlock(&mutex, &timeout) != ETIMEDOUT) { perror("Error in pthread_mutex_timedlock().\n"); pthread_exit((void *)PTS_UNRESOLVED); return (void *)PTS_UNRESOLVED; } /* Get time after the mutex timed out in locking. */ gettimeofday(&currsec2, NULL); pthread_exit(0); return (void *)(0); }
bool timed_lock(system_time const & abs_time) { struct timespec const timeout=detail::get_timespec(abs_time); int const res=pthread_mutex_timedlock(&m,&timeout); BOOST_ASSERT(!res || res==ETIMEDOUT); return !res; }
int main(int argc, char *argv[]) { int retcode; use_timeout = (argc >= 2 && strcmp(argv[1], "-t") == 0); if (is_help_requested(argc, argv)) { usage(argv[0], ""); } timeout.tv_sec = (time_t) 200; timeout.tv_nsec = (long) 0; if (use_timeout && argc >= 3) { int t; sscanf(argv[2], "%d", &t); timeout.tv_sec = (time_t) t; } printf("timout(%ld sec %ld msec)\n", (long) timeout.tv_sec, (long) timeout.tv_nsec); pthread_t thread[N_THREADS]; int tidx[N_THREADS]; for (size_t i = 0; i < N_THREADS; i++) { tidx[i] = (int) i; retcode = pthread_create(thread + i, NULL, run, (void *) (tidx + i)); // equivalent: ((void *) tidx) + sizeof(int)*i handle_thread_error(retcode, "creating thread failed", PROCESS_EXIT); } printf("in parent: setting up\n"); pthread_mutex_init(&mutex, NULL); sleep(2); printf("in parent: getting mutex\n"); if (use_timeout) { while (TRUE) { retcode = pthread_mutex_timedlock(&mutex, &timeout); if (retcode == 0) { break; } else if (retcode == ETIMEDOUT) { printf("timed out in parent\n"); } else { handle_thread_error(retcode, "parent failed (timed)lock", PROCESS_EXIT); } } } else { retcode = pthread_mutex_lock(&mutex); handle_thread_error(retcode, "parent failed lock", PROCESS_EXIT); } printf("parent got mutex\n"); sleep(5); printf("parent releases mutex\n"); pthread_mutex_unlock(&mutex); printf("parent released mutex\n"); printf("parent waiting for child to terminate\n"); for (size_t i = 0; i < N_THREADS; i++) { retcode = pthread_join(thread[i], NULL); handle_thread_error(retcode, "join failed", PROCESS_EXIT); printf("joined thread %d\n", (int) i); } pthread_mutex_destroy(&mutex); printf("done\n"); exit(0); }
//------------------------------------------------------------------------------ // Function: ShbIpcEnterAtomicSection // // Description: Enter atomic section for Shared Buffer access // // Parameters: pShbInstance_p pointer to shared buffer instance // // Return: tShbError = error code //------------------------------------------------------------------------------ tShbError ShbIpcEnterAtomicSection (tShbInstance pShbInstance_p) { tShbMemInst *pShbMemInst; tShbMemHeader *pShbMemHeader; tShbError ShbError; struct timespec curTime, timeout; if (pShbInstance_p == NULL) { return (kShbInvalidArg); } pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p); pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst); clock_gettime(CLOCK_REALTIME, &curTime); timeout.tv_sec = 0; timeout.tv_nsec = TIMEOUT_ENTER_ATOMIC * 1000; timespecadd(&timeout, &curTime); if (pthread_mutex_timedlock(&pShbMemHeader->m_mutexBuffAccess, &timeout) == 0) { ShbError = kShbOk; } else { ShbError = kShbBufferInvalid; } return (ShbError); }
int pthread_mutex_lock(pthread_mutex_t* m) { if ((m->_m_type & PTHREAD_MUTEX_MASK) == PTHREAD_MUTEX_NORMAL && !a_cas_shim(&m->_m_lock, 0, EBUSY)) return 0; return pthread_mutex_timedlock(m, 0); }
void *run(void *arg) { int *argi = (int *) arg; int my_tidx = *argi; int retcode; printf("in child %d: sleeping\n", my_tidx); sleep(2); if (use_timeout) { while (TRUE) { retcode = pthread_mutex_timedlock(&mutex, &timeout); if (retcode == 0) { break; } else if (retcode == ETIMEDOUT) { printf("timed out in child %d\n", my_tidx); sleep(1); } else { handle_thread_error(retcode, "child failed timed lock", PROCESS_EXIT); } } } else { retcode = pthread_mutex_lock(&mutex); handle_thread_error(retcode, "child failed lock", PROCESS_EXIT); } printf("child %d got mutex\n", my_tidx); char line[1025]; fgets(line, 1024, stdin); printf("[%d]: %s\n", my_tidx, line); sleep(1); printf("child %d releases mutex\n", my_tidx); pthread_mutex_unlock(&mutex); printf("child %d released mutex\n", my_tidx); sleep(10); printf("child %d exiting\n", my_tidx); return NULL; }
bool timedlock(int64_t milliseconds) const { #if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L PROFILE_MUTEX_START_LOCK(); struct timespec ts; Util::toTimespec(ts, milliseconds + Util::currentTime()); int ret = pthread_mutex_timedlock(&pthread_mutex_, &ts); if (ret == 0) { PROFILE_MUTEX_LOCKED(); return true; } PROFILE_MUTEX_NOT_LOCKED(); return false; #else /* Otherwise follow solution used by Mono for Android */ struct timespec sleepytime, now, to; /* This is just to avoid a completely busy wait */ sleepytime.tv_sec = 0; sleepytime.tv_nsec = 10000000L; /* 10ms */ Util::toTimespec(to, milliseconds + Util::currentTime()); while ((trylock()) == false) { Util::toTimespec(now, Util::currentTime()); if (now.tv_sec >= to.tv_sec && now.tv_nsec >= to.tv_nsec) { return false; } nanosleep(&sleepytime, NULL); } return true; #endif }
static void f() { pthread_t td; int r; pthread_mutexattr_t mtx_a; pthread_mutex_t mtx; struct timespec ts; T(r, pthread_barrier_init(&barrier2, 0, 2)); T(r, pthread_mutexattr_init(&mtx_a)); T(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST)); if (pshared) T(r, pthread_mutexattr_setpshared(&mtx_a, PTHREAD_PROCESS_SHARED)); T(r, pthread_mutex_init(&mtx, &mtx_a)); T(r, pthread_create(&td, 0, start_lock, &mtx)); T(r, pthread_detach(td)); pthread_barrier_wait(&barrier2); pthread_barrier_destroy(&barrier2); // enough time to ensure that the detached thread is dead clock_gettime(CLOCK_REALTIME, &ts); ts.tv_nsec += 100*1000*1000; if (ts.tv_nsec >= 1000*1000*1000) { ts.tv_sec++; ts.tv_nsec -= 1000*1000*1000; } TX(r, pthread_mutex_timedlock(&mtx, &ts), EOWNERDEAD); }
PUBLIC int csoundWaitThreadLock(void *lock, size_t milliseconds) { { register int retval = pthread_mutex_trylock((pthread_mutex_t*) lock); if (!retval) return retval; if (!milliseconds) return retval; } { struct timeval tv; struct timespec ts; register size_t n, s; #ifndef HAVE_GETTIMEOFDAY gettimeofday_(&tv, NULL); #else gettimeofday(&tv, NULL); #endif s = milliseconds / (size_t) 1000; n = milliseconds - (s * (size_t) 1000); s += (size_t) tv.tv_sec; n = (size_t) (((int) n * 1000 + (int) tv.tv_usec) * 1000); ts.tv_nsec = (long) (n < (size_t) 1000000000 ? n : n - 1000000000); ts.tv_sec = (time_t) (n < (size_t) 1000000000 ? s : s + 1); return pthread_mutex_timedlock((pthread_mutex_t*) lock, &ts); } }
void *thread_tb(void *arg) { unsigned long timeoutsec; struct timespec boost_time; double t0, t1; int rc; test_set_priority(pthread_self(), SCHED_FIFO, 4); DPRINTF(stderr,"Thread TB: started\n"); timeoutsec = *(unsigned long*) arg; DPRINTF(stdout, "#EVENT %f TB Started, waiting for mutex for %lu s\n", seconds_read() - base_time, timeoutsec); boost_time.tv_sec = time(NULL) + (time_t)timeoutsec; boost_time.tv_nsec = 0; t0 = seconds_read(); rc = pthread_mutex_timedlock(&mutex, &boost_time); t1 = seconds_read(); DPRINTF(stdout, "#EVENT %f TB Thread Waited for %.2f s\n", seconds_read() - base_time, t1 - t0); if (rc != ETIMEDOUT && rc != 0){ EPRINTF("FAIL: Thread TB: lock returned %d %s, " "slept %f", rc, strerror(rc), t1 - t0); exit(FAIL); } DPRINTF(stdout, "#EVENT %f TB Stopped\n", seconds_read() - base_time); return NULL; }
static void * th (void *arg) { long int res = 0; int r; struct timespec t = { -2, 0 }; r = pthread_mutex_timedlock (&m1, &t); if (r != ETIMEDOUT) { puts ("pthread_mutex_timedlock did not return ETIMEDOUT"); res = 1; } r = pthread_rwlock_timedrdlock (&rw1, &t); if (r != ETIMEDOUT) { puts ("pthread_rwlock_timedrdlock did not return ETIMEDOUT"); res = 1; } r = pthread_rwlock_timedwrlock (&rw2, &t); if (r != ETIMEDOUT) { puts ("pthread_rwlock_timedwrlock did not return ETIMEDOUT"); res = 1; } return (void *) res; }
void *thread_tb2(void *arg) { struct timespec boost_time; double t0, t1; int rc; test_set_priority(pthread_self(), SCHED_FIFO, 6); DPRINTF(stderr, "Thread TB2: started\n"); DPRINTF(stdout, "#EVENT %f TB2 Thread Started\n", seconds_read() - base_time); boost_time.tv_sec = time(NULL) + *(time_t *) arg; boost_time.tv_nsec = 0; t0 = seconds_read(); rc = pthread_mutex_timedlock(&mutex, &boost_time); t1 = seconds_read(); DPRINTF(stdout, "#EVENT %f TB2 Thread Waited for %.2f s\n", t1 - base_time, t1 - t0); if (rc != ETIMEDOUT && rc != 0) { EPRINTF("FAIL: Thread TB2: lock returned %d %s, " "slept %f", rc, strerror(rc), t1 - t0); exit(FAIL); } return NULL; }
static void *i_Print_Data(void *pData) { unsigned int idx = (unsigned int)pData; struct timespec abs_time; int retVal = 0; /* abs_time = now + 3sec */ clock_gettime(CLOCK_REALTIME, &abs_time); printf("This is thread with no %d\n", idx); abs_time.tv_sec += 15; /* Try to lock the ressource again. we shall time out in 3 seconds. */ retVal = pthread_mutex_timedlock (&mutexLock, &abs_time); if (retVal != 0) { printf("Wait timed out"); } for (idx = 0; idx < MAX_NO; idx++) { printf("Data Element = %d\n", ascendNo[idx]); } /* Mutex Un-Lock */ pthread_mutex_unlock(&mutexLock); return (0); }
inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) { #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS timespec ts = detail::ptime_to_timespec(abs_time); int res = pthread_mutex_timedlock(&m_mut, &ts); if (res != 0 && res != ETIMEDOUT) throw lock_exception(); return res == 0; #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS //Obtain current count and target time boost::posix_time::ptime now = microsec_clock::universal_time(); if(now >= abs_time) return false; do{ if(this->try_lock()){ break; } now = microsec_clock::universal_time(); if(now >= abs_time){ return false; } // relinquish current time slice detail::thread_yield(); }while (true); return true; #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS }
static int try_lock(pthread_mutex_t *mtx) { int rc = pthread_mutex_trylock(mtx); switch (rc) { case 0: break; case EBUSY: { struct timespec tim; clock_gettime(CLOCK_REALTIME, &tim); tim.tv_nsec += (double) 0.05 * (double) SEC2NANO; rc = pthread_mutex_timedlock(mtx, &tim); if (rc) return -1; } break; case EINVAL: default: rc = -1; break; } return rc; }
/* gcc apue.h apue_err.c figure-11.13.c -lpthread -lrt */ int main(void) { int err; struct timespec tout; struct tm *tmp; char buf[64]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); printf("mutex is locked\n"); clock_gettime(CLOCK_REALTIME, &tout); /* 编译时需要 -lrt */ tmp = localtime(&tout.tv_sec); strftime(buf, sizeof(buf), "%r", tmp); printf("current time is now %s\n", buf); tout.tv_sec += 10; /* 10 seconds from now */ /* caution: this could lead to deadlock */ err = pthread_mutex_timedlock(&lock, &tout); clock_gettime(CLOCK_REALTIME, &tout); tmp = localtime(&tout.tv_sec); strftime(buf, sizeof(buf), "%r", tmp); printf("the time is now %s\n", buf); if (err == 0) printf("mutex locked again!\n"); else printf("can't lock mutex again:%s\n", strerror(err)); exit(0); }
int Mutex_Lock(IN HANDLE hm, IN DWORD dwWaitTimeout) { MUTEX *pMutex = (MUTEX *)hm; struct timespec ts; long nWaitSeconds, nWaitNonaseconds; time_t tmEndTime; if (hm == NULL) { return ERR_INVALID_ARGS; } nWaitSeconds = (long)MS_TO_SEC(dwWaitTimeout); // sec nWaitNonaseconds = (long)MS_TO_NS(dwWaitTimeout%MS_PER_SEC); // nonasec clock_gettime(CLOCK_REALTIME, &ts); // get the start time. ts.tv_nsec += nWaitNonaseconds; if (ts.tv_nsec > NS_PER_SEC) { ts.tv_sec += 1; ts.tv_nsec -= NS_PER_SEC; } tmEndTime = ts.tv_sec; #ifdef _DEBUG_MUTEX TRACE("[Mutex_Lock] -- lock and wait %d ms at %d\n", (int)dwWaitTimeout, (int)tmEndTime); #endif //_DEBUG_MUTEX while (nWaitSeconds >= 0) { // get the end of the real time. tmEndTime += ((nWaitSeconds < MAX_WAIT_INTERVAL) ? nWaitSeconds : MAX_WAIT_INTERVAL); ts.tv_sec = tmEndTime; // do NOT change ts.tv_nsec. if (pthread_mutex_timedlock(&pMutex->hInternalMutex, &ts) == 0) { return ERR_MUTEX_OK; } nWaitSeconds -= MAX_WAIT_INTERVAL; if (nWaitSeconds >= 0) { RUN_THREAD_HEARTBEAT(); } } #ifdef _DEBUG_MUTEX TRACE("[Mutex_Lock] -- lock timeouted at %d\n", (int)time(NULL)); #endif //_DEBUG_MUTEX // if goes here, timeout on trying to lock. return ERR_MUTEX_TIMEOUT; }
int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { int ret; struct timespec ts; uint32_t sec, nsec; csp_log_lock("Wait: %p timeout %"PRIu32"\r\n", mutex, timeout); if (timeout == CSP_INFINITY) { ret = pthread_mutex_lock(mutex); } else { if (clock_gettime(CLOCK_REALTIME, &ts)) return CSP_SEMAPHORE_ERROR; sec = timeout / 1000; nsec = (timeout - 1000 * sec) * 1000000; ts.tv_sec += sec; if (ts.tv_nsec + nsec >= 1000000000) ts.tv_sec++; ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; ret = pthread_mutex_timedlock(mutex, &ts); } if (ret != 0) return CSP_SEMAPHORE_ERROR; return CSP_SEMAPHORE_OK; }
int swMutex_lockwait(swLock *lock, int timeout_msec) { struct timespec timeo; timeo.tv_sec = timeout_msec / 1000; timeo.tv_nsec = (timeout_msec - timeo.tv_sec * 1000) * 1000 * 1000; return pthread_mutex_timedlock(&lock->object.mutex._lock, &timeo); }
unsigned long mutexLock(LPDM_MUTEX m, int timeout) { #ifdef WIN32 int to = timeout > 0 ? timeout : INFINITE; return WaitForSingleObject(m, to); #else struct timespec to; int ret; if(timeout > 0) { to.tv_sec = timeout / 1000; to.tv_nsec = (timeout % 1000) * 1000000; ret = pthread_mutex_timedlock(m->mutex, &to); }else{ ret = pthread_mutex_trylock(m->mutex); if(ret == EOWNERDEAD){ pthread_mutex_consistent(m->mutex); pthread_mutex_unlock(m->mutex); ret = pthread_mutex_lock(m->mutex); }else if(ret == EBUSY){ ret = pthread_mutex_lock(m->mutex); } } return ret; #endif }
extern "C" int pthread_mutex_lock(pthread_mutex_t* lock) { struct timespec timeout; memset(&timeout, 0, sizeof timeout); timeout.tv_sec = TIMEOUT_S; pid_t tid = syscall(SYS_gettid); RELEASE_ASSERT(tid > 1, "negative or invalid TID"); time_t started = time(NULL); RELEASE_ASSERT(started != (time_t)-1, "could not get time()"); int err; for (;;) { err = pthread_mutex_timedlock(lock, &timeout); if (err != ETIMEDOUT) break; time_t now = time(NULL); RELEASE_ASSERT(now != (time_t)-1, "could not get time()"); if (now - started >= TIMEOUT_S) { printf("%d: mutex %p TIMED OUT\n", tid, (void*)lock); started = now; } } RELEASE_ASSERT(!err, "could not lock mutex, error %d", err); return err; }
int TSLockMutex(TSMutex *mutex, struct timespec *timeout) { if (NULL == timeout) { return pthread_mutex_lock(&mutex->_mutex); } else if (0 == pthread_mutex_trylock(&mutex->_mutex)) { return 0; } else { struct timespec abs_timeout; clock_gettime(CLOCK_REALTIME, &abs_timeout); abs_timeout.tv_sec += timeout->tv_sec; abs_timeout.tv_nsec += timeout->tv_nsec; if (abs_timeout.tv_nsec > 1000000000) { abs_timeout.tv_sec++; abs_timeout.tv_nsec -= 1000000000; } return pthread_mutex_timedlock(&mutex->_mutex, &abs_timeout); } }
static int my_pthread_mutex_lock_timeout_np(pthread_mutex_t *__mutex, unsigned __msecs) { struct timespec tv; pthread_mutex_t *realmutex; unsigned int value = (*(unsigned int *) __mutex); if (hybris_check_android_shared_mutex(value)) { LOGD("Shared mutex with Android, not lock timeout np."); return 0; } realmutex = (pthread_mutex_t *) value; if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) { realmutex = hybris_alloc_init_mutex(value); *((int *)__mutex) = (int) realmutex; } /* TODO: Android uses CLOCK_MONOTONIC here but I am not sure which one to use */ clock_gettime(CLOCK_REALTIME, &tv); tv.tv_sec += __msecs/1000; tv.tv_nsec += (__msecs % 1000) * 1000000; if (tv.tv_nsec >= 1000000000) { tv.tv_sec++; tv.tv_nsec -= 1000000000; } return pthread_mutex_timedlock(realmutex, &tv); }