int osd_lock_try(osd_lock *lock) { return (pthread_mutex_trylock((pthread_mutex_t *) lock) ? FALSE : TRUE); }
int call_trylock() { return pthread_mutex_trylock(&call_mutex); }
int __cilkrts_os_mutex_trylock(struct os_mutex *p) { int status; status = pthread_mutex_trylock (&p->mutex); return (status == 0); }
bool PThreadMutex::TryEnter() { return pthread_mutex_trylock(&mutex) == 0; }
int pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock) { int result, result1; pthread_rwlock_t rwl; if (rwlock == NULL || *rwlock == NULL) { return EINVAL; } /* * We do a quick check to see if we need to do more work * to initialise a static rwlock. We check * again inside the guarded section of ptw32_rwlock_check_need_init() * to avoid race conditions. */ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) { result = ptw32_rwlock_check_need_init (rwlock); if (result != 0 && result != EBUSY) { return result; } } rwl = *rwlock; if (rwl->nMagic != PTW32_RWLOCK_MAGIC) { return EINVAL; } if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0) { return result; } if ((result = pthread_mutex_trylock (&(rwl->mtxSharedAccessCompleted))) != 0) { result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); return ((result1 != 0) ? result1 : result); } if (rwl->nExclusiveAccessCount == 0) { if (rwl->nCompletedSharedAccessCount > 0) { rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; rwl->nCompletedSharedAccessCount = 0; } if (rwl->nSharedAccessCount > 0) { if ((result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) { (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); return result; } if ((result = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) == 0) { result = EBUSY; } } else { rwl->nExclusiveAccessCount = 1; } } else { result = EBUSY; } return result; }
int main ( void ) { int r; /* pthread_t thr; */ /* pthread_attr_t thra; */ pthread_mutexattr_t mxa, mxa2; pthread_mutex_t mx, mx2, mx3, mx4; pthread_cond_t cv; struct timespec abstime; pthread_rwlock_t rwl; pthread_rwlock_t rwl2; pthread_rwlock_t rwl3; sem_t s1; # if __GLIBC_PREREQ(2,4) fprintf(stderr, "\n\n------ This is output for >= glibc 2.4 ------\n"); # else fprintf(stderr, "\n\n------ This is output for < glibc 2.4 ------\n"); # endif /* --------- pthread_create/join --------- */ fprintf(stderr, "\n---------------- pthread_create/join ----------------\n\n"); /* make pthread_create fail */ /* It's amazingly difficult to make pthread_create fail without first soaking up all the machine's resources. Instead, in order to demonstrate that it's really wrapped, create a child thread, generate a race error, and join with it again. */ /* This just segfaults: memset( &thra, 0xFF, sizeof(thra) ); r= pthread_create( &thr, NULL, lazy_child, NULL ); assert(r); */ { pthread_t child; r= pthread_create( &child, NULL, racy_child, NULL ); assert(!r); sleep(1); /* just to ensure parent thread reports race, not child */ unprotected = 5678; r= pthread_join( child, NULL ); assert(!r); } /* make pthread_join fail */ r= pthread_join( pthread_self(), NULL ); assert(r); /* --------- pthread_mutex_lock et al --------- */ fprintf(stderr, "\n---------------- pthread_mutex_lock et al ----------------\n\n"); /* make pthread_mutex_init fail */ #if defined(__sun__) pthread_mutexattr_init( &mxa ); memset( mxa.__pthread_mutexattrp, 0xFF, 5 * sizeof(int) ); #else memset( &mxa, 0xFF, sizeof(mxa) ); #endif r= pthread_mutex_init( &mx, &mxa ); # if __GLIBC_PREREQ(2,4) assert(r); /* glibc >= 2.4: the call should fail */ # else assert(!r); /* glibc < 2.4: oh well, glibc didn't bounce this */ # endif /* make pthread_mutex_destroy fail */ r= pthread_mutex_init( &mx2, NULL ); assert(!r); r= pthread_mutex_lock( &mx2 ); assert(!r); r= pthread_mutex_destroy( &mx2 ); /* make pthread_mutex_lock fail (skipped on < glibc 2.4 because it doesn't fail, hence hangs the test) */ # if __GLIBC_PREREQ(2,4) memset( &mx3, 0xFF, sizeof(mx3) ); r= pthread_mutex_lock( &mx3 ); assert(r); # else fprintf(stderr, "\nmake pthread_mutex_lock fail: " "skipped on glibc < 2.4\n\n"); # endif /* make pthread_mutex_trylock fail */ memset( &mx3, 0xFF, sizeof(mx3) ); r= pthread_mutex_trylock( &mx3 ); assert(r); /* make pthread_mutex_timedlock fail */ memset( &abstime, 0, sizeof(abstime) ); memset( &mx3, 0xFF, sizeof(mx3) ); r= pthread_mutex_timedlock( &mx3, &abstime ); assert(r); /* make pthread_mutex_unlock fail */ memset( &mx3, 0xFF, sizeof(mx3) ); r= pthread_mutex_unlock( &mx3 ); # if __GLIBC_PREREQ(2,4) assert(r); # else assert(!r); # endif /* --------- pthread_cond_wait et al --------- */ fprintf(stderr, "\n---------------- pthread_cond_wait et al ----------------\n\n"); /* make pthread_cond_wait fail. This is difficult. Our cunning plan (tm) is to show up at pthread_cond_wait bearing a not-locked mutex of the ERRORCHECK flavour and hope (as is indeed the case with glibc-2.5) that pthread_cond_wait notices it is not locked, and bounces our request. */ r= pthread_mutexattr_init( &mxa2 ); assert(!r); r= pthread_mutexattr_settype( &mxa2, PTHREAD_MUTEX_ERRORCHECK ); assert(!r); r= pthread_mutex_init( &mx4, &mxa2 ); assert(!r); r= pthread_cond_init( &cv, NULL ); assert(!r); r= pthread_cond_wait( &cv, &mx4 ); assert(r); r= pthread_mutexattr_destroy( &mxa2 ); assert(!r); /* make pthread_cond_signal fail. FIXME: can't figure out how to */ r= pthread_cond_signal( &cv ); assert(!r); fprintf(stderr, "\nFIXME: can't figure out how to " "verify wrap of pthread_cond_signal\n\n"); /* make pthread_cond_broadcast fail. FIXME: can't figure out how to */ r= pthread_cond_broadcast( &cv ); assert(!r); fprintf(stderr, "\nFIXME: can't figure out how to " "verify wrap of pthread_broadcast_signal\n\n"); /* make pthread_cond_timedwait fail. */ memset( &abstime, 0, sizeof(abstime) ); abstime.tv_nsec = 1000000000 + 1; r= pthread_cond_timedwait( &cv, &mx4, &abstime ); assert(r); /* --------- pthread_rwlock_* --------- */ fprintf(stderr, "\n---------------- pthread_rwlock_* ----------------\n\n"); /* pthread_rwlock_init, pthread_rwlock_unlock */ /* pthread_rwlock_init: can't make glibc's implementation fail. However, can demonstrate interceptedness by initialising but not locking a lock and then unlocking it. Then the unlock call should say "first seen at .. the init call." So this tests wrappedness of both calls. */ r= pthread_rwlock_init( &rwl, NULL ); assert(!r); r= pthread_rwlock_unlock( &rwl ); /* assert(r); *//* glibc doesn't complain. It really ought to. Oh well. */ /* We can infer the presence of wrapping for pthread_rwlock_rdlock, pthread_rwlock_wrlock and pthread_rwlock_unlock by making Thrcheck count the lockedness state, and warning when we unlock a not-locked lock. Thusly: */ r= pthread_rwlock_init( &rwl2, NULL ); assert(!r); /* w-lock it */ fprintf(stderr, "(1) no error on next line\n"); r= pthread_rwlock_wrlock( &rwl2 ); assert(!r); /* unlock it */ fprintf(stderr, "(2) no error on next line\n"); r= pthread_rwlock_unlock( &rwl2 ); assert(!r); /* unlock it again, get an error */ fprintf(stderr, "(3) ERROR on next line\n"); r= pthread_rwlock_unlock( &rwl2 ); #if defined(__sun__) assert(r); #else assert(!r); #endif /* same game with r-locks */ r= pthread_rwlock_init( &rwl2, NULL ); assert(!r); /* r-lock it twice */ fprintf(stderr, "(4) no error on next line\n"); r= pthread_rwlock_rdlock( &rwl2 ); assert(!r); fprintf(stderr, "(5) no error on next line\n"); r= pthread_rwlock_rdlock( &rwl2 ); assert(!r); /* unlock it twice */ fprintf(stderr, "(6) no error on next line\n"); r= pthread_rwlock_unlock( &rwl2 ); assert(!r); fprintf(stderr, "(7) no error on next line\n"); r= pthread_rwlock_unlock( &rwl2 ); assert(!r); /* unlock it again, get an error */ fprintf(stderr, "(8) ERROR on next line\n"); r= pthread_rwlock_unlock( &rwl2 ); #if defined(__sun__) assert(r); #else assert(!r); #endif /* Lock rwl3 so the locked-lock-at-dealloc check can complain about it. */ r= pthread_rwlock_init( &rwl3, NULL ); assert(!r); r= pthread_rwlock_rdlock( &rwl3 ); assert(!r); /* ------------- sem_* ------------- */ /* This is pretty lame, and duplicates tc18_semabuse.c. */ fprintf(stderr, "\n---------------- sem_* ----------------\n\n"); /* verifies wrap of sem_init */ /* Do sem_init with huge initial count - fails */ r= sem_init(&s1, 0, ~0); assert(r); /* initialise properly */ r= sem_init(&s1, 0, 0); /* in glibc, sem_destroy is a no-op; making it fail is impossible. */ fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of " "sem_destroy\n\n"); /* verifies wrap of sem_wait */ /* Do 'wait' on a bogus semaphore. This should fail, but on glibc it succeeds. */ memset(&s1, 0x55, sizeof(s1)); r= sem_wait(&s1); /* assert(r != 0); */ /* this only fails with glibc 2.7 or later. */ r= sem_post(&s1); fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of " "sem_post\n\n"); sem_destroy(&s1); /* ------------- dealloc of mem holding locks ------------- */ fprintf(stderr, "\n------------ dealloc of mem holding locks ------------\n\n"); /* At this point it should complain about deallocation of memory containing locked locks: rwl3 */ return 0; }
bool Mutex::trylock() { return (pthread_mutex_trylock(&(this->_m)) == 0); }
int my_pthread_mutex_trylock (pthread_mutex_t *__mutex) { pthread_mutex_t *realmutex = late_init_pthread_mutex(__mutex); return pthread_mutex_trylock(realmutex); }
bool CAMutex::Try(bool& outWasLocked) { bool theAnswer = false; outWasLocked = false; #if TARGET_OS_MAC pthread_t theCurrentThread = pthread_self(); if(!pthread_equal(theCurrentThread, mOwner)) { // this means the current thread doesn't already own the lock #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); #endif // go ahead and call trylock to see if we can lock it. int theError = pthread_mutex_trylock(&mMutex); if(theError == 0) { // return value of 0 means we successfully locked the lock mOwner = theCurrentThread; theAnswer = true; outWasLocked = true; #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); #endif } else if(theError == EBUSY) { // return value of EBUSY means that the lock was already locked by another thread theAnswer = false; outWasLocked = false; #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); #endif } else { // any other return value means something really bad happenned ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed"); } } else { // this means the current thread already owns the lock theAnswer = true; outWasLocked = false; } #elif TARGET_OS_WIN32 if(mOwner != GetCurrentThreadId()) { // this means the current thread doesn't own the lock #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); #endif // try to acquire the mutex OSStatus theError = WaitForSingleObject(mMutex, 0); if(theError == WAIT_OBJECT_0) { // this means we successfully locked the lock mOwner = GetCurrentThreadId(); theAnswer = true; outWasLocked = true; #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); #endif } else if(theError == WAIT_TIMEOUT) { // this means that the lock was already locked by another thread theAnswer = false; outWasLocked = false; #if Log_Ownership DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); #endif } else { // any other return value means something really bad happenned ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed"); } } else { // this means the current thread already owns the lock theAnswer = true; outWasLocked = false; } #endif return theAnswer; }
bool CLinuxMutex::TryLock() { //pthread_mutex_trylock returns 0 if lock is acquired. //Will return EBUSY if lock is not acquired return pthread_mutex_trylock(&_mtx) == 0; }
int core_queue_packet(struct packet *p, unsigned int flags, unsigned int thread_affinity) { // Update the counters registry_perf_inc(p->input->perf_pkts_in, 1); registry_perf_inc(p->input->perf_bytes_in, p->len); if (!core_run) return POM_ERR; debug_core("Queuing packet %p (%u.%06u)", p, pom_ptime_sec(p->ts), pom_ptime_usec(p->ts)); // Find the right thread to queue to struct core_processing_thread *t = NULL; if (flags & CORE_QUEUE_HAS_THREAD_AFFINITY) { t = core_processing_threads[thread_affinity % core_num_threads]; pom_mutex_lock(&t->pkt_queue_lock); } else { static volatile unsigned int start = 0; unsigned int i; while (1) { unsigned int thread_id = start; for (i = 0; i < core_num_threads; i++) { thread_id++; if (thread_id >= core_num_threads) thread_id -= core_num_threads; t = core_processing_threads[thread_id]; int res = pthread_mutex_trylock(&t->pkt_queue_lock); if (res == EBUSY) { // Thread is busy, go to the next one continue; } else if (res) { pomlog(POMLOG_ERR "Error while locking a processing thread pkt_queue mutex : %s", pom_strerror(res)); abort(); return POM_ERR; } // We've got the lock, check if it's ok to queue here if (t->pkt_count < CORE_THREAD_PKT_QUEUE_MAX) { // Use this thread break; } // Too many packets pending in this thread, go to the next one pom_mutex_unlock(&t->pkt_queue_lock); } if (i < core_num_threads) { // We locked on a thread start = thread_id; break; } // No thread found if (core_pkt_queue_count >= ((CORE_THREAD_PKT_QUEUE_MAX - 1) * core_num_threads)) { // Queue full if (flags & CORE_QUEUE_DROP_IF_FULL) { packet_release(p); registry_perf_inc(perf_pkt_dropped, 1); debug_core("Dropped packet %p (%u.%06u) to thread %u", p, pom_ptime_sec(p->ts), pom_ptime_usec(p->ts)); return POM_OK; } // We're not going to drop this. Wait then debug_core("All queues full. Waiting ..."); pom_mutex_lock(&core_pkt_queue_wait_lock); // Recheck the count after locking if (core_pkt_queue_count >= ((CORE_THREAD_PKT_QUEUE_MAX - 1) * core_num_threads)) { int res = pthread_cond_wait(&core_pkt_queue_wait_cond, &core_pkt_queue_wait_lock); if (res) { pomlog(POMLOG_ERR "Error while waiting for the core pkt_queue condition : %s", pom_strerror(res)); abort(); } } pom_mutex_unlock(&core_pkt_queue_wait_lock); } } } // We've got the thread's lock, add it to the queue struct core_packet_queue *tmp = NULL; if (t->pkt_queue_unused) { tmp = t->pkt_queue_unused; t->pkt_queue_unused = tmp->next; } else { tmp = malloc(sizeof(struct core_packet_queue)); if (!tmp) { pom_mutex_unlock(&t->pkt_queue_lock); pom_oom(sizeof(struct core_packet_queue)); return POM_ERR; } } tmp->pkt = p; tmp->next = NULL; if (t->pkt_queue_tail) { t->pkt_queue_tail->next = tmp; } else { t->pkt_queue_head = tmp; // The queue was empty, we need to signal it int res = pthread_cond_signal(&t->pkt_queue_cond); if (res) { pomlog(POMLOG_ERR "Error while signaling the thread pkt_queue restart condition : %s", pom_strerror(res)); abort(); return POM_ERR; } } t->pkt_queue_tail = tmp; t->pkt_count++; __sync_fetch_and_add(&core_pkt_queue_count, 1); registry_perf_inc(perf_pkt_queue, 1); debug_core("Queued packet %p (%u.%06u) to thread %u", p, pom_ptime_sec(p->ts), pom_ptime_usec(p->ts), t->thread_id); pom_mutex_unlock(&t->pkt_queue_lock); return POM_OK; }
static int do_test (void) { size_t ps = sysconf (_SC_PAGESIZE); char tmpfname[] = "/tmp/tst-mutex4.XXXXXX"; char data[ps]; void *mem; int fd; pthread_mutex_t *m; pthread_mutexattr_t a; pid_t pid; char *p; int err; int s; pthread_barrier_t *b; pthread_barrierattr_t ba; fd = mkstemp (tmpfname); if (fd == -1) { printf ("cannot open temporary file: %m\n"); return 1; } /* Make sure it is always removed. */ unlink (tmpfname); /* Create one page of data. */ memset (data, '\0', ps); /* Write the data to the file. */ if (write (fd, data, ps) != (ssize_t) ps) { puts ("short write"); return 1; } mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { printf ("mmap failed: %m\n"); return 1; } m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1) & ~(__alignof (pthread_mutex_t) - 1)); b = (pthread_barrier_t *) (((uintptr_t) (m + 1) + __alignof (pthread_barrier_t) - 1) & ~(__alignof (pthread_barrier_t) - 1)); p = (char *) (b + 1); if (pthread_mutexattr_init (&a) != 0) { puts ("mutexattr_init failed"); return 1; } if (pthread_mutexattr_getpshared (&a, &s) != 0) { puts ("1st mutexattr_getpshared failed"); return 1; } if (s != PTHREAD_PROCESS_PRIVATE) { puts ("default pshared value wrong"); return 1; } if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("mutexattr_setpshared failed"); return 1; } if (pthread_mutexattr_getpshared (&a, &s) != 0) { puts ("2nd mutexattr_getpshared failed"); return 1; } if (s != PTHREAD_PROCESS_SHARED) { puts ("pshared value after setpshared call wrong"); return 1; } #ifdef ENABLE_PI if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0) { puts ("pthread_mutexattr_setprotocol failed"); return 1; } #endif if ((err = pthread_mutex_init (m, &a)) != 0) { #ifdef ENABLE_PI if (err == ENOTSUP) { puts ("PI mutexes unsupported"); return 0; } #endif puts ("mutex_init failed"); return 1; } if (pthread_mutex_lock (m) != 0) { puts ("mutex_lock failed"); return 1; } if (pthread_mutexattr_destroy (&a) != 0) { puts ("mutexattr_destroy failed"); return 1; } if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); return 1; } err = pthread_mutex_trylock (m); if (err == 0) { puts ("mutex_trylock succeeded"); return 1; } else if (err != EBUSY) { puts ("mutex_trylock didn't return EBUSY"); return 1; } *p = 0; if (pthread_mutex_unlock (m) != 0) { puts ("parent: 1st mutex_unlock failed"); return 1; } puts ("going to fork now"); pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } else if (pid == 0) { if (pthread_mutex_lock (m) != 0) { puts ("child: mutex_lock failed"); return 1; } int e = pthread_barrier_wait (b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { puts ("child: barrier_wait failed"); return 1; } if ((*p)++ != 0) { puts ("child: *p != 0"); return 1; } if (pthread_mutex_unlock (m) != 0) { puts ("child: mutex_unlock failed"); return 1; } puts ("child done"); } else { int e = pthread_barrier_wait (b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { puts ("parent: barrier_wait failed"); return 1; } if (pthread_mutex_lock (m) != 0) { puts ("parent: 2nd mutex_lock failed"); return 1; } if (*p != 1) { puts ("*p != 1"); return 1; } if (pthread_mutex_unlock (m) != 0) { puts ("parent: 2nd mutex_unlock failed"); return 1; } if (pthread_mutex_destroy (m) != 0) { puts ("mutex_destroy failed"); return 1; } if (pthread_barrier_destroy (b) != 0) { puts ("barrier_destroy failed"); return 1; } puts ("parent done"); } return 0; }
inline int mutex_try_lock(mutex_t m) { return pthread_mutex_trylock(&m->m_mutex); }
int main(int argc, char *argv[]) { int seed; int d, i, sm; pthread_mutexattr_t mattr; pthread_mutex_t *mutex; // imposta il seme seed=time(NULL); srand(seed); // se non e' stato chiamato col numero corretto di argomenti // termina if (argc!=2) { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } // contralla se sei il processo da lanciare per primo if (!strcmp("first",argv[1])) { d=-1; printf("First process\n"); } // o come secondo else if (!strcmp("second",argv[1])) { d=1; printf("Second process\n"); } // altrimenti esci else { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } // ottieni il tuo pid printf("Pid:%d\n",getpid()); // imposta il segnale di terminazione wanna_exit=0; signal(SIGUSR1,sig_user_exit); // se sei il primo processo if (d==-1) { // prova a creare il file che mappa la memoria condivisa if ((sm=shm_open("/shared_mtx",O_CREAT|O_EXCL|O_RDWR,S_IRUSR|S_IWUSR))<0) { // se esiste una vecchia copia rimasta aperta if (errno==EEXIST) { // prova ad eliminarla shm_unlink("/shared_mtx"); printf("Removing /shared_mtx\n"); // e a creare il file, esci nel caso di errore if ((sm=shm_open("/shared_mtx",O_CREAT|O_EXCL|O_RDWR,S_IRUSR|S_IWUSR))<0) { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } } else { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } } } // altrimenti else { // prova ad aprire il file che mappa la memoria condivisa if ((sm=shm_open("/shared_mtx",O_RDWR,S_IRUSR|S_IWUSR))<0) { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } } // se sei il primo processo if (d==-1) // imposta le dimensioni del file/memoria condivisa per // contenere il mutex if (ftruncate(sm,sizeof(pthread_mutex_t))<0) { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } // mappa il file associato alla memoria ottenura dal sistema // per la condivisone nel proprio spazio di memoria if ((mutex=(void *)mmap(NULL,sizeof(pthread_mutex_t),PROT_WRITE|PROT_READ,MAP_SHARED,sm,0))==MAP_FAILED) { printf("Error !!! File %s, line %d\n",__FILE__,__LINE__); exit(EXIT_FAILURE); } printf("Shared mutex obtained\n"); // se sei il primo processo if (d==-1) { // inizializza il mutex per essere condiviso tra processi // e non solo tra thread pthread_mutexattr_init(&mattr); pthread_mutexattr_setpshared(&mattr,PTHREAD_PROCESS_SHARED); pthread_mutex_init(mutex,&mattr); pthread_mutexattr_destroy(&mattr); printf("Mutex initialized\n"); } // finche' non si deve uscire while (!wanna_exit) { // genera un intervallo casuale i=rand()%9+1; // esci se richiesto if (wanna_exit) { printf("Exit...\n"); break; } // o vai a dormire printf("Going to sleep for %d sec...\n",i); sleep(i); // esci se richiesto if (wanna_exit) { printf("Exit...\n"); break; } // prova ad ottenere il mutex if (pthread_mutex_trylock(mutex)) { printf("Wait for the mutex...\n"); pthread_mutex_lock(mutex); } // quando l'hai ottenuto // genera un intervallo casuale i=rand()%9+1; // esci se richiesto dopo aver rilasciato il mutex if (wanna_exit) { pthread_mutex_unlock(mutex); printf("Exit...\n"); break; } // altrimenti dormi printf("Mutex obtained and now wait for %d sec...\n",i); sleep(i); // se si deve uscire rilascia prima il mutex if (wanna_exit) { pthread_mutex_unlock(mutex); printf("Exit...\n"); break; } // sblocca il mutex printf("Unlock mutex...\n"); pthread_mutex_unlock(mutex); } // abbiamo finito e rimuoviamo l'associazione della file condiviso // alla memoria del processo munmap(mutex,sizeof(pthread_mutex_t)); // se siamo il primo processo if (d==-1) { // impostiamo la cancellazione del file/memoria condivisa // (verra' effettivamente rimosso quando tutti i processi che lo // condividono chiuderanno il descrittore relativo (in questo // caso alla terminazione del processo) shm_unlink("/shared_mtx"); printf("Removing shared mutex\n"); } exit(EXIT_SUCCESS); }
PUBLIC int csoundLockMutexNoWait(void *mutex_) { return pthread_mutex_trylock((pthread_mutex_t*) mutex_); }
bool try_lock() { return pthread_mutex_trylock(&_pmutex) == 0; }
int conntrack_get_unique_from_parent(struct proto_process_stack *stack, unsigned int stack_index) { struct conntrack_node_list *child = NULL; struct conntrack_list *lst = NULL; struct proto_process_stack *s = &stack[stack_index]; struct proto_process_stack *s_prev = &stack[stack_index - 1]; struct conntrack_entry *parent = s_prev->ce; if (!s->proto) { pomlog(POMLOG_ERR "Cannot allocate conntrack for NULL proto"); return POM_ERR; } if (!parent) { pomlog(POMLOG_ERR "Cannot allocate unique conntrack without a parent"); return POM_ERR; } if (s->ce) { // This should only occur in the case that an expectation matched // Make sure the conntrack is locked int res = pthread_mutex_trylock(&s->ce->lock); if (res && res != EBUSY && res == EDEADLK) { pomlog(POMLOG_ERR "Error while locking the conntrack : %s", pom_strerror(res)); return POM_ERR; } return POM_OK; } conntrack_lock(parent); struct conntrack_tables *ct = s->proto->ct; struct conntrack_entry *res = NULL; // Look for the conntrack if (parent->children) { struct conntrack_node_list *child = parent->children; for (child = parent->children; child && child->ce->proto != s->proto; child = child->next); if (child) res = child->ce; } if (!res) { // Alloc the conntrack res = malloc(sizeof(struct conntrack_entry)); if (!res) { pom_oom(sizeof(struct conntrack_entry)); goto err; } memset(res, 0, sizeof(struct conntrack_entry)); res->proto = s->proto; if (pom_mutex_init_type(&res->lock, PTHREAD_MUTEX_ERRORCHECK) != POM_OK) goto err; // Alloc the child list child = malloc(sizeof(struct conntrack_node_list)); if (!child) goto err; memset(child, 0, sizeof(struct conntrack_node_list)); child->ce = res; child->ct = ct; // Alloc the parent node res->parent = malloc(sizeof(struct conntrack_node_list)); if (!res->parent) { free(child); goto err; } memset(res->parent, 0, sizeof(struct conntrack_node_list)); res->parent->ce = parent; res->parent->ct = parent->proto->ct; res->parent->hash = parent->hash; // Alloc the list node lst = malloc(sizeof(struct conntrack_list)); if (!lst) { pom_oom(sizeof(struct conntrack_list)); goto err; } memset(lst, 0, sizeof(struct conntrack_list)); lst->ce = res; // Add the child to the parent child->next = parent->children; if (child->next) child->next->prev = child; parent->children = child; // Add the conntrack to the table pom_mutex_lock(&ct->locks[0]); lst->next = ct->table[0]; if (lst->next) lst->next->prev = lst; ct->table[0] = lst; pom_mutex_unlock(&ct->locks[0]); debug_conntrack("Allocated conntrack %p with parent %p (uniq child)", res, parent); registry_perf_inc(s->proto->perf_conn_cur, 1); registry_perf_inc(s->proto->perf_conn_tot, 1); } conntrack_unlock(parent); conntrack_lock(res); res->refcount++; s->ce = res; s->direction = s_prev->direction; struct proto_process_stack *s_next = &stack[stack_index + 1]; s_next->direction = s->direction; return POM_OK; err: if (res) { pthread_mutex_destroy(&res->lock); free(res); } if (child) free(child); conntrack_unlock(parent); return POM_ERR; }
/// Non-blocking attempt to acquire a lock on the mutex inline bool try_lock() const { return pthread_mutex_trylock( &m_mut ) == 0; }
/************************************************************************* * * Function: sql_get_socket * * Purpose: Return a SQL sqlsocket from the connection pool * *************************************************************************/ SQLSOCK * sql_get_socket(SQL_INST * inst) { SQLSOCK *cur, *start; int tried_to_connect = 0; int unconnected = 0; time_t now = time(NULL); /* * Start at the last place we left off. */ start = inst->last_used; if (!start) start = inst->sqlpool; cur = start; while (cur) { #ifdef HAVE_PTHREAD_H /* * If this socket is in use by another thread, * skip it, and try another socket. * * If it isn't used, then grab it ourselves. */ if (pthread_mutex_trylock(&cur->mutex) != 0) { goto next; } /* else we now have the lock */ #endif /* * If the socket has outlived its lifetime, and * is connected, close it, and mark it as open for * reconnections. */ if (inst->config->lifetime && (cur->state == sockconnected) && ((cur->connected + inst->config->lifetime) < now)) { DEBUG2("Closing socket %d as its lifetime has been exceeded", cur->id); (inst->module->sql_close)(cur, inst->config); cur->state = sockunconnected; goto reconnect; } /* * If we have performed too many queries over this * socket, then close it. */ if (inst->config->max_queries && (cur->state == sockconnected) && (cur->queries >= inst->config->max_queries)) { DEBUG2("Closing socket %d as its max_queries has been exceeded", cur->id); (inst->module->sql_close)(cur, inst->config); cur->state = sockunconnected; goto reconnect; } /* * If we happen upon an unconnected socket, and * this instance's grace period on * (re)connecting has expired, then try to * connect it. This should be really rare. */ if ((cur->state == sockunconnected) && (now > inst->connect_after)) { reconnect: radlog(L_INFO, "rlm_sql (%s): Trying to (re)connect unconnected handle %d..", inst->config->xlat_name, cur->id); tried_to_connect++; connect_single_socket(cur, inst); } /* if we still aren't connected, ignore this handle */ if (cur->state == sockunconnected) { DEBUG("rlm_sql (%s): Ignoring unconnected handle %d..", inst->config->xlat_name, cur->id); unconnected++; #ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&cur->mutex); #endif goto next; } /* should be connected, grab it */ DEBUG("rlm_sql (%s): Reserving sql socket id: %d", inst->config->xlat_name, cur->id); if (unconnected != 0 || tried_to_connect != 0) { DEBUG("rlm_sql (%s): got socket %d after skipping %d unconnected handles, tried to reconnect %d though", inst->config->xlat_name, cur->id, unconnected, tried_to_connect); } /* * The socket is returned in the locked * state. * * We also remember where we left off, * so that the next search can start from * here. * * Note that multiple threads MAY over-write * the 'inst->last_used' variable. This is OK, * as it's a pointer only used for reading. */ inst->last_used = cur->next; cur->queries++; return cur; /* move along the list */ next: cur = cur->next; /* * Because we didnt start at the start, once we * hit the end of the linklist, we should go * back to the beginning and work toward the * middle! */ if (!cur) { cur = inst->sqlpool; } /* * If we're at the socket we started */ if (cur == start) { break; } } /* * Suppress most of the log messages. We don't want to * flood the log with this message for EVERY packet. * Instead, write to the log only once a second or so. * * This code has race conditions when threaded, but the * only result is that a few more messages are logged. */ if (now <= last_logged_failure) return NULL; last_logged_failure = now; /* We get here if every DB handle is unconnected and unconnectABLE */ radlog(L_INFO, "rlm_sql (%s): There are no DB handles to use! skipped %d, tried to connect %d", inst->config->xlat_name, unconnected, tried_to_connect); return NULL; }
void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose) { int trylock = pthread_mutex_trylock( &queue->run_mutex ); if (trylock != 0) util_abort("%s: another thread is already running the queue_manager\n",__func__); else if (!queue->user_exit) { /* OK - we have got an exclusive lock to the run_jobs code. */ //Check if queue is open. Fails hard if not open job_queue_check_open(queue); /* The number of threads in the thread pool running callbacks. Memory consumption can potentially be quite high while running the DONE callback - should therefor not use too many threads. */ const int NUM_WORKER_THREADS = 4; queue->work_pool = thread_pool_alloc( NUM_WORKER_THREADS , true ); { bool new_jobs = false; bool cont = true; int phase = 0; queue->running = true; do { bool local_user_exit = false; job_list_get_rdlock( queue->job_list ); /*****************************************************************/ if (queue->user_exit) {/* An external thread has called the job_queue_user_exit() function, and we should kill all jobs, do some clearing up and go home. Observe that we will go through the queue handling codeblock below ONE LAST TIME before exiting. */ job_queue_user_exit__( queue ); local_user_exit = true; } job_queue_check_expired(queue); /*****************************************************************/ { bool update_status = job_queue_update_status( queue ); if (verbose) { if (update_status || new_jobs) job_queue_print_summary(queue , update_status ); job_queue_update_spinner( &phase ); } { int num_complete = job_queue_status_get_count(queue->status, JOB_QUEUE_SUCCESS) + job_queue_status_get_count(queue->status, JOB_QUEUE_FAILED) + job_queue_status_get_count(queue->status, JOB_QUEUE_IS_KILLED); if ((num_total_run > 0) && (num_total_run == num_complete)) /* The number of jobs completed is equal to the number of jobs we have said we want to run; so we are finished. */ cont = false; else { if (num_total_run == 0) { /* We have not informed about how many jobs we will run. To check if we are complete we perform the two tests: 1. All the jobs which have been added with job_queue_add_job() have completed. 2. The user has used job_queue_complete_submit() to signal that no more jobs will be forthcoming. */ if ((num_complete == job_list_get_size( queue->job_list )) && queue->submit_complete) cont = false; } } } if (cont) { /* Submitting new jobs */ int max_submit = 5; /* This is the maximum number of jobs submitted in one while() { ... } below. Only to ensure that the waiting time before a status update is not too long. */ int total_active = job_queue_status_get_count(queue->status, JOB_QUEUE_PENDING) + job_queue_status_get_count(queue->status, JOB_QUEUE_RUNNING); int num_submit_new; { int max_running = job_queue_get_max_running( queue ); if (max_running > 0) num_submit_new = util_int_min( max_submit , max_running - total_active ); else /* If max_running == 0 that should be interpreted as no limit; i.e. the queue layer will attempt to send an unlimited number of jobs to the driver - the driver can reject the jobs. */ num_submit_new = util_int_min( max_submit , job_queue_status_get_count(queue->status, JOB_QUEUE_WAITING)); } new_jobs = false; if (job_queue_status_get_count(queue->status, JOB_QUEUE_WAITING) > 0) /* We have waiting jobs at all */ if (num_submit_new > 0) /* The queue can allow more running jobs */ new_jobs = true; if (new_jobs) { int submit_count = 0; int queue_index = 0; while ((queue_index < job_list_get_size( queue->job_list )) && (num_submit_new > 0)) { job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); if (job_queue_node_get_status(node) == JOB_QUEUE_WAITING) { { submit_status_type submit_status = job_queue_submit_job(queue , queue_index); if (submit_status == SUBMIT_OK) { num_submit_new--; submit_count++; } else if ((submit_status == SUBMIT_DRIVER_FAIL) || (submit_status == SUBMIT_QUEUE_CLOSED)) break; } } queue_index++; } } { /* Checking for complete / exited / overtime jobs */ int queue_index; for (queue_index = 0; queue_index < job_list_get_size( queue->job_list ); queue_index++) { job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); switch (job_queue_node_get_status(node)) { case(JOB_QUEUE_DONE): job_queue_handle_DONE(queue, node); break; case(JOB_QUEUE_EXIT): job_queue_handle_EXIT(queue, node); break; case(JOB_QUEUE_DO_KILL_NODE_FAILURE): job_queue_handle_DO_KILL_NODE_FAILURE(queue, node); break; case(JOB_QUEUE_DO_KILL): job_queue_handle_DO_KILL(queue, node); break; default: break; } } } } else /* print an updated status to stdout before exiting. */ if (verbose) job_queue_print_summary(queue , true); } job_list_unlock( queue->job_list ); if (local_user_exit) cont = false; /* This is how we signal that we want to get out . */ else { util_yield(); job_list_reader_wait( queue->job_list , queue->usleep_time , 8 * queue->usleep_time); } } while ( cont ); } if (verbose) printf("\n"); thread_pool_join( queue->work_pool ); thread_pool_free( queue->work_pool ); } /* Set the queue's "open" flag to false to signal that the queue is not ready to be used in a new job_queue_run_jobs or job_queue_add_job method call as it has not been reset yet. Not resetting the queue here implies that the queue object is still available for queries after this method has finished */ queue->open = false; queue->running = false; pthread_mutex_unlock( &queue->run_mutex ); }
int NaClFastMutexTryLock(struct NaClFastMutex *flp) { return NaClXlateErrno(pthread_mutex_trylock(&flp->mu)); }
/* * This thread waits for ANT messages from a VFS file. */ void *fnRxThread(void *ant_rx_thread_info) { int iMutexLockResult; int iPollRet; ant_rx_thread_info_t *stRxThreadInfo; struct pollfd astPollFd[NUM_POLL_FDS]; ant_channel_type eChannel; ANT_FUNC_START(); stRxThreadInfo = (ant_rx_thread_info_t *)ant_rx_thread_info; for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { astPollFd[eChannel].fd = stRxThreadInfo->astChannels[eChannel].iFd; astPollFd[eChannel].events = EVENTS_TO_LISTEN_FOR; } // Fill out poll request for the shutdown signaller. astPollFd[EVENTFD_IDX].fd = stRxThreadInfo->iRxShutdownEventFd; astPollFd[EVENTFD_IDX].events = POLL_IN; // Reset the waiting for response, since we don't want a stale value if we were reset. stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; /* continue running as long as not terminated */ while (stRxThreadInfo->ucRunThread) { /* Wait for data available on any file (transport path), shorter wait if we just timed out. */ int timeout = stRxThreadInfo->bWaitingForKeepaliveResponse ? KEEPALIVE_TIMEOUT : ANT_POLL_TIMEOUT; iPollRet = poll(astPollFd, NUM_POLL_FDS, timeout); if (!iPollRet) { if(!stRxThreadInfo->bWaitingForKeepaliveResponse) { stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_TRUE; // Keep alive is done on a separate thread so that rxThread can handle flow control during // the message. pthread_t thread; // Don't care if it failed as the consequence is just a missed keep-alive. pthread_create(&thread, NULL, fnKeepAliveThread, NULL); // Detach the thread so that we don't need to join it later. pthread_detach(thread); ANT_DEBUG_V("poll timed out, checking exit cond"); } else { ANT_DEBUG_E("No response to keepalive, attempting recovery."); doReset(stRxThreadInfo); goto out; } } else if (iPollRet < 0) { ANT_ERROR("unhandled error: %s, attempting recovery.", strerror(errno)); doReset(stRxThreadInfo); goto out; } else { for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_HARD_RESET)) { ANT_ERROR("Hard reset indicated by %s. Attempting recovery.", stRxThreadInfo->astChannels[eChannel].pcDevicePath); doReset(stRxThreadInfo); goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_CHIP_SHUTDOWN)) { /* chip reported it was unexpectedly disabled */ ANT_DEBUG_D( "poll hang-up from %s. Attempting recovery.", stRxThreadInfo->astChannels[eChannel].pcDevicePath); doReset(stRxThreadInfo); goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DATA_AVAILABLE)) { ANT_DEBUG_D("data on %s. reading it", stRxThreadInfo->astChannels[eChannel].pcDevicePath); // Doesn't matter what data we received, we know the chip is alive. stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; if (readChannelMsg(eChannel, &stRxThreadInfo->astChannels[eChannel]) < 0) { ANT_ERROR("Read of data failed. Attempting recovery."); doReset(stRxThreadInfo); goto out; } } else if (areAllFlagsSet(astPollFd[eChannel].revents, POLLNVAL)) { ANT_ERROR("poll was called on invalid file descriptor %s. Attempting recovery.", stRxThreadInfo->astChannels[eChannel].pcDevicePath); doReset(stRxThreadInfo); goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, POLLERR)) { ANT_ERROR("Unknown error from %s. Attempting recovery.", stRxThreadInfo->astChannels[eChannel].pcDevicePath); doReset(stRxThreadInfo); goto out; } else if (astPollFd[eChannel].revents) { ANT_DEBUG_W("unhandled poll result %#x from %s", astPollFd[eChannel].revents, stRxThreadInfo->astChannels[eChannel].pcDevicePath); } } // Now check for shutdown signal if(areAllFlagsSet(astPollFd[EVENTFD_IDX].revents, POLLIN)) { ANT_DEBUG_I("rx thread caught shutdown signal."); // reset the counter by reading. uint64_t counter; read(stRxThreadInfo->iRxShutdownEventFd, &counter, sizeof(counter)); // don't care if read error, going to close the thread anyways. stRxThreadInfo->ucRunThread = 0; } else if (astPollFd[EVENTFD_IDX].revents != 0) { ANT_ERROR("Shutdown event descriptor had unexpected event: %#x. exiting rx thread.", astPollFd[EVENTFD_IDX].revents); stRxThreadInfo->ucRunThread = 0; } } } /* disable ANT radio if not already disabling */ // Try to get stEnabledStatusLock. // if you get it then no one is enabling or disabling // if you can't get it assume something made you exit ANT_DEBUG_V("try getting stEnabledStatusLock in %s", __FUNCTION__); iMutexLockResult = pthread_mutex_trylock(stRxThreadInfo->pstEnabledStatusLock); if (!iMutexLockResult) { ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__); ANT_WARN("rx thread has unexpectedly crashed, cleaning up"); // spoof our handle as closed so we don't try to join ourselves in disable stRxThreadInfo->stRxThread = 0; if (g_fnStateCallback) { g_fnStateCallback(RADIO_STATUS_DISABLING); } ant_disable(); if (g_fnStateCallback) { g_fnStateCallback(ant_radio_enabled_status()); } ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__); pthread_mutex_unlock(stRxThreadInfo->pstEnabledStatusLock); ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__); } else if (iMutexLockResult != EBUSY) { ANT_ERROR("rx thread closing code, trylock on state lock failed: %s", strerror(iMutexLockResult)); } else { ANT_DEBUG_V("stEnabledStatusLock busy"); } out: ANT_FUNC_END(); #ifdef ANDROID return NULL; #endif }
void memories::lock() { if(m_memmutex == NULL) return; while(pthread_mutex_trylock(m_memmutex) == EBUSY) pthread_testcancel(); }
bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }
// Evict Page returns the location of the lowest open slot in the provided memory level // If there are no open spots, it uses the paging algorithm to evict one page from the memlev // and move it to the next one. int evict_page(Memlev memlev) { // printf("Trying to evict a page.\n"); // Interate through the entire page table // If there is still room available in ram // find the lowest available location and return the data int i; int max_elements = 0; // This switch case determines the memory level the eviction is on // if the provided memlevel is "nul" or "hdd", not page can be // evicted and an error value of -2 is returned. switch(memlev){ case ram: // printf("Trying to evict page from ram\n"); max_elements = MAXRAM; break; case ssd: // printf("Trying to evict page from ssd\n"); max_elements = MAXSSD; break; case hdd: // printf("Trying to evict page from hdd\n"); max_elements = MAXHDD; break; default: printf("Trying to evict page from the 'nul' level\n"); return -2; break; break; } // This is the list of all the available pageframes in a memlev // 1 = taken, 0 = available int slots[max_elements]; // Iterate through the entire page table, marking all the taken pageframes for(int i = 0; i < max_elements; i++){ slots[i] = 0; } // Iterate through the entire page table, marking all the taken pageframes for(i = 0; i < MAXADDR; i++){ if(page_table[i].memlev == memlev && page_table[i].empty == 0){ slots[page_table[i].location] = 1; } } // Once all the take page frames are marked, see if any are still available for(i = 0; i < max_elements; i++){ // If there is a pageframe available // update the location with the ram information and return it. if(slots[i] == 0){ switch(memlev){ case ram: // printf("Trying to lock ram slot %i\n", i); if(pthread_mutex_trylock(&(lock_ram[i])) == 0){ // printf("Successfully locked ram slot %i\n", i); return i; } // printf("Failed to lock ram slot %i\n", i); break; case ssd: if(pthread_mutex_trylock(&(lock_ssd[i])) == 0){ return i; } break; case hdd: if(pthread_mutex_trylock(&(lock_hdd[i])) == 0){ return i; } break; break; } } } // If there are no spots in this memory level, // then we will have to move a page out // and into the higher memory level // Here we call evict on the next memory level // to find a place to move the evicted page // printf("'We need to go deeper'\n"); int new_slot = evict_page(memlev + 1); if(new_slot < 0){ printf("There is a serious problem\n"); } // We call our custom algorithm to find a page to evict vAddr temp_page = page_to_remove(memlev, type_r); // finally we move the content to the higher memory level switch(memlev) { case ram: write_to_memory(ssd, new_slot, read_from_memory(ram, page_table[temp_page].location)); break; case ssd: write_to_memory(hdd, new_slot, read_from_memory(ssd, page_table[temp_page].location)); break; break; } // update it's paging information to reflect the new position page_table[temp_page].memlev = memlev + 1; int result = page_table[temp_page].location; page_table[temp_page].location = new_slot; // Unlock the modified page pthread_mutex_unlock(&(page_table[temp_page].lock)); // And return the newly opened pageframe return result; }
//------------------------------------------------------------------------------ // rcu_check -- //------------------------------------------------------------------------------ void rcu_check() { if (deferred_work > 0 && pthread_mutex_trylock(&rcu_mutex) == 0) { rcu_xxxx(); pthread_mutex_unlockx(&rcu_mutex); } }
bool cThreadLock::TryLock() { return pthread_mutex_trylock( &m_lock ) == 0; }
bool TCriticalSection::TryEnter() { return pthread_mutex_trylock(&Cs); }
/// Non-blocking attempt to acquire a lock on the mutex inline bool try_lock() const { #ifdef _WIN32 if (locked) return false; #endif return pthread_mutex_trylock( &m_mut ) == 0; }
_PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) { void *ptr; pthread_mutex_t *m; pthread_mutexattr_t ma; int ret = 1; int pipe_down[2] = { -1, -1 }; int pipe_up[2] = { -1, -1 }; ssize_t nread; char c = 0; bool ok; int status; static bool initialized; if (initialized) { return tdb_mutex_locking_cached; } initialized = true; ok = tdb_mutex_locking_supported(); if (!ok) { return false; } tdb_mutex_locking_cached = false; ptr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1 /* fd */, 0); if (ptr == MAP_FAILED) { return false; } m = (pthread_mutex_t *)ptr; ret = pipe(pipe_down); if (ret != 0) { goto cleanup_mmap; } ret = pipe(pipe_up); if (ret != 0) { goto cleanup_pipe; } ret = pthread_mutexattr_init(&ma); if (ret != 0) { goto cleanup_pipe; } ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); if (ret != 0) { goto cleanup_ma; } ret = pthread_mutex_init(m, &ma); if (ret != 0) { goto cleanup_ma; } if (tdb_robust_mutex_setup_sigchild(tdb_robust_mutex_handler, &tdb_robust_mutext_old_handler) == false) { goto cleanup_ma; } tdb_robust_mutex_pid = fork(); if (tdb_robust_mutex_pid == 0) { size_t nwritten; close(pipe_down[1]); close(pipe_up[0]); ret = pthread_mutex_lock(m); nwritten = write(pipe_up[1], &ret, sizeof(ret)); if (nwritten != sizeof(ret)) { _exit(1); } if (ret != 0) { _exit(1); } nread = read(pipe_down[0], &c, 1); if (nread != 1) { _exit(1); } /* leave locked */ _exit(0); } if (tdb_robust_mutex_pid == -1) { goto cleanup_sig_child; } close(pipe_down[0]); pipe_down[0] = -1; close(pipe_up[1]); pipe_up[1] = -1; nread = read(pipe_up[0], &ret, sizeof(ret)); if (nread != sizeof(ret)) { goto cleanup_child; } ret = pthread_mutex_trylock(m); if (ret != EBUSY) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup_child; } if (write(pipe_down[1], &c, 1) != 1) { goto cleanup_child; } nread = read(pipe_up[0], &c, 1); if (nread != 0) { goto cleanup_child; } while (tdb_robust_mutex_pid > 0) { pid_t pid; errno = 0; pid = waitpid(tdb_robust_mutex_pid, &status, 0); if (pid == tdb_robust_mutex_pid) { tdb_robust_mutex_pid = -1; break; } if (pid == -1 && errno != EINTR) { goto cleanup_child; } } tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL); ret = pthread_mutex_trylock(m); if (ret != EOWNERDEAD) { if (ret == 0) { pthread_mutex_unlock(m); } goto cleanup_m; } ret = pthread_mutex_consistent(m); if (ret != 0) { goto cleanup_m; } ret = pthread_mutex_trylock(m); if (ret != EDEADLK) { pthread_mutex_unlock(m); goto cleanup_m; } ret = pthread_mutex_unlock(m); if (ret != 0) { goto cleanup_m; } tdb_mutex_locking_cached = true; goto cleanup_m; cleanup_child: while (tdb_robust_mutex_pid > 0) { pid_t pid; kill(tdb_robust_mutex_pid, SIGKILL); errno = 0; pid = waitpid(tdb_robust_mutex_pid, &status, 0); if (pid == tdb_robust_mutex_pid) { tdb_robust_mutex_pid = -1; break; } if (pid == -1 && errno != EINTR) { break; } } cleanup_sig_child: tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL); cleanup_m: pthread_mutex_destroy(m); cleanup_ma: pthread_mutexattr_destroy(&ma); cleanup_pipe: if (pipe_down[0] != -1) { close(pipe_down[0]); } if (pipe_down[1] != -1) { close(pipe_down[1]); } if (pipe_up[0] != -1) { close(pipe_up[0]); } if (pipe_up[1] != -1) { close(pipe_up[1]); } cleanup_mmap: munmap(ptr, sizeof(pthread_mutex_t)); return tdb_mutex_locking_cached; }