int pth_rwlock_acquire(pth_rwlock_t *rwlock, int op, int tryonly, pth_event_t ev_extra) { /* consistency checks */ if (rwlock == NULL) return pth_error(FALSE, EINVAL); if (!(rwlock->rw_state & PTH_RWLOCK_INITIALIZED)) return pth_error(FALSE, EDEADLK); /* acquire lock */ if (op == PTH_RWLOCK_RW) { /* read-write lock is simple */ if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra)) return FALSE; rwlock->rw_mode = PTH_RWLOCK_RW; } else { /* read-only lock is more complicated to get right */ if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), tryonly, ev_extra)) return FALSE; rwlock->rw_readers++; if (rwlock->rw_readers == 1) { if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra)) { rwlock->rw_readers--; pth_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); } return FALSE; } } rwlock->rw_mode = PTH_RWLOCK_RD; pth_mutex_release(&(rwlock->rw_mutex_rd)); }
int main() { pth_t thread; int rc; int i, j, s; arg = -1; res = 0; pth_init(); thread = pth_spawn(PTH_ATTR_DEFAULT, thread_routine, NULL); for(i = 0; i < 100; i++) { s = 0; for(j = 0; j < 10000; j++) { pth_mutex_acquire(&mutex, FALSE, NULL); res = -1; arg = j; pth_mutex_release(&mutex); pth_cond_notify(&c1, FALSE); pth_mutex_acquire(&mutex, FALSE, NULL); if(res < 0) pth_cond_await(&c2, &mutex, NULL); s += res; arg = -1; pth_mutex_release(&mutex); } } printf("%d\n", s); return 0; }
/* Returns True is the pinentry is currently active. If WAITSECONDS is greater than zero the function will wait for this many seconds before returning. */ int pinentry_active_p (ctrl_t ctrl, int waitseconds) { (void)ctrl; if (waitseconds > 0) { pth_event_t evt; int rc; evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0)); if (!pth_mutex_acquire (&entry_lock, 0, evt)) { if (pth_event_occurred (evt)) rc = gpg_error (GPG_ERR_TIMEOUT); else rc = gpg_error (GPG_ERR_INTERNAL); pth_event_free (evt, PTH_FREE_THIS); return rc; } pth_event_free (evt, PTH_FREE_THIS); } else { if (!pth_mutex_acquire (&entry_lock, 1, NULL)) return gpg_error (GPG_ERR_LOCKED); } if (!pth_mutex_release (&entry_lock)) log_error ("failed to release the entry lock at %d\n", __LINE__); return 0; }
/* Lock a mutex. A return value of 0 indicates success */ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp) { TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id())); #ifdef TSRM_WIN32 EnterCriticalSection(mutexp); return 0; #elif defined(GNUPTH) if (pth_mutex_acquire(mutexp, 0, NULL)) { return 0; } return -1; #elif defined(PTHREADS) return pthread_mutex_lock(mutexp); #elif defined(NSAPI) crit_enter(mutexp); return 0; #elif defined(PI3WEB) return PISync_lock(mutexp); #elif defined(TSRM_ST) return st_mutex_lock(mutexp); #elif defined(BETHREADS) if (atomic_add(&mutexp->ben, 1) != 0) return acquire_sem(mutexp->sem); return 0; #endif }
/* Initialize the mutex *PRIV. If JUST_CHECK is true, only do this if it is not already initialized. */ static int mutex_pth_init (ath_mutex_t *priv, int just_check) { int err = 0; if (just_check) pth_mutex_acquire (&check_init_lock, 0, NULL); if (!*priv || !just_check) { pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); if (!lock) err = ENOMEM; if (!err) { err = pth_mutex_init (lock); if (err == FALSE) err = errno; else err = 0; if (err) free (lock); else *priv = (ath_mutex_t) lock; } } if (just_check) pth_mutex_release (&check_init_lock); return err; }
static int mutex_entry( pth_mutex_t *mutex ) { if ( !pth_init_called ) { pth_init(); pth_init_called = 1; } return pth_mutex_acquire( mutex, 0, NULL ); }
static int mutex_entry( void ) { if ( !pth_init_called ) { pth_init(); pth_init_called = 1; } return pth_mutex_acquire( &mutex_log, 0, NULL ); }
static void putdown(unsigned int k) { pth_mutex_acquire(&(tab->mutex), FALSE, NULL); (tab->status)[k] = thinking; printstate(); test((k + 1) % PHILNUM); test((k - 1 + PHILNUM) % PHILNUM); pth_mutex_release(&(tab->mutex)); return; }
int ath_mutex_lock (ath_mutex_t *lock) { int ret = mutex_pth_init (lock, 1); if (ret) return ret; ret = pth_mutex_acquire ((pth_mutex_t *) *lock, 0, NULL); return ret == FALSE ? errno : 0; }
static void pickup(unsigned int k) { pth_mutex_acquire(&(tab->mutex), FALSE, NULL); (tab->status)[k] = hungry; printstate(); if (!test(k)) pth_cond_await(&((tab->condition)[k]), &(tab->mutex), NULL); printstate(); pth_mutex_release(&(tab->mutex)); return; }
/* Lock the mutex */ int SDL_mutexP(SDL_mutex *mutex) { if ( mutex == NULL ) { SDL_SetError("Passed a NULL mutex"); return -1; } pth_mutex_acquire(&(mutex->mutexpth_p), FALSE, NULL); return(0); }
void * thread_routine(void *dummy) { while(1) { pth_mutex_acquire(&mutex, FALSE, NULL); if(arg < 0) pth_cond_await(&c1, &mutex, NULL); res = arg; arg = -1; pth_mutex_release(&mutex); pth_cond_notify(&c2, FALSE); } }
Array < eibaddr_t > GroupCache::LastUpdates (uint16_t start, uint8_t Timeout, uint16_t & end, pth_event_t stop) { Array < eibaddr_t > a; pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (Timeout, 0)); do { if (pos < 0x100) { if (pos < start && start < ((pos - 0x100) & 0xffff)) start = (pos - 0x100) & 0xffff; } else { if (start < ((pos - 0x100) & 0xffff) || start > pos) start = (pos - 0x100) & 0xffff; } TRACEPRINTF (t, 8, this, "LastUpdates start: %d pos: %d", start, pos); while (start != pos && !updates[start & 0xff]) start++; if (start != pos) { while (start != pos) { if (updates[start & 0xff]) a.add (updates[start & 0xff]); start++; } end = pos; pth_event_free (timeout, PTH_FREE_THIS); return a; } if (pth_event_status (timeout) == PTH_STATUS_OCCURRED) { end = pos; pth_event_free (timeout, PTH_FREE_THIS); return a; } pth_event_concat (timeout, stop, NULL); pth_mutex_acquire (&mutex, 0, 0); pth_cond_await (&cond, &mutex, timeout); pth_mutex_release (&mutex); pth_event_isolate (timeout); } while (1); }
/* Lock a mutex. A return value of 0 indicates success */ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp) {/*{{{*/ TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id())); #ifdef TSRM_WIN32 EnterCriticalSection(mutexp); return 0; #elif defined(GNUPTH) if (pth_mutex_acquire(mutexp, 0, NULL)) { return 0; } return -1; #elif defined(PTHREADS) return pthread_mutex_lock(mutexp); #elif defined(TSRM_ST) return st_mutex_lock(mutexp); #endif }/*}}}*/
int ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) { return( pth_mutex_acquire( mutex, 1, NULL ) ? 0 : errno ); }
GroupCacheEntry GroupCache::Read (eibaddr_t addr, unsigned Timeout, uint16_t age) { TRACEPRINTF (t, 4, this, "GroupCacheRead %s %d %d", FormatGroupAddr (addr)(), Timeout, age); bool rm = false; GroupCacheEntry *c; if (!enable) { GroupCacheEntry f; f.src = 0; f.dst = 0; TRACEPRINTF (t, 4, this, "GroupCache not enabled"); return f; } c = find (addr); if (c && age && c->recvtime + age < time (0)) rm = true; if (c && !rm) { TRACEPRINTF (t, 4, this, "GroupCache found: %s", FormatEIBAddr (c->src)()); return *c; } if (!Timeout) { GroupCacheEntry f; f.src = 0; f.dst = addr; TRACEPRINTF (t, 4, this, "GroupCache no entry"); return f; } A_GroupValue_Read_PDU apdu; T_DATA_XXX_REQ_PDU tpdu; L_Data_PDU *l; pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (Timeout, 0)); tpdu.data = apdu.ToPacket (); l = new L_Data_PDU (FakeL2); l->data = tpdu.ToPacket (); l->source = 0; l->dest = addr; l->AddrType = GroupAddress; layer3->send_L_Data (l); do { c = find (addr); rm = false; if (c && age && c->recvtime + age < time (0)) rm = true; if (c && !rm) { TRACEPRINTF (t, 4, this, "GroupCache found: %s", FormatEIBAddr (c->src)()); pth_event_free (timeout, PTH_FREE_THIS); return *c; } if (pth_event_status (timeout) == PTH_STATUS_OCCURRED && c) { GroupCacheEntry gc; gc.src = 0; gc.dst = addr; TRACEPRINTF (t, 4, this, "GroupCache reread timeout"); pth_event_free (timeout, PTH_FREE_THIS); return gc; } if (pth_event_status (timeout) == PTH_STATUS_OCCURRED) { c = new GroupCacheEntry; c->src = 0; c->dst = addr; c->recvtime = time (0); add (c); TRACEPRINTF (t, 4, this, "GroupCache timeout"); pth_event_free (timeout, PTH_FREE_THIS); return *c; } pth_mutex_acquire (&mutex, 0, 0); pth_cond_await (&cond, &mutex, timeout); pth_mutex_release (&mutex); } while (1); }
void FrSimThreadCondVar::lock() { pth_mutex_acquire(&mutex, false, NULL); isLocked = true; }
static void lock_trusttable (void) { if (!pth_mutex_acquire (&trusttable_lock, 0, NULL)) log_fatal ("failed to acquire mutex in %s\n", __FILE__); }
/* Fork off the pin entry if this has not already been done. Note, that this function must always be used to aquire the lock for the pinentry - we will serialize _all_ pinentry calls. */ static int start_pinentry (ctrl_t ctrl) { int rc; const char *pgmname; assuan_context_t ctx; const char *argv[5]; int no_close_list[3]; int i; pth_event_t evt; const char *tmpstr; unsigned long pinentry_pid; const char *value; evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); if (!pth_mutex_acquire (&entry_lock, 0, evt)) { if (pth_event_occurred (evt)) rc = gpg_error (GPG_ERR_TIMEOUT); else rc = gpg_error (GPG_ERR_INTERNAL); pth_event_free (evt, PTH_FREE_THIS); log_error (_("failed to acquire the pinentry lock: %s\n"), gpg_strerror (rc)); return rc; } pth_event_free (evt, PTH_FREE_THIS); entry_owner = ctrl; if (entry_ctx) return 0; if (opt.verbose) log_info ("starting a new PIN Entry\n"); #ifdef HAVE_W32_SYSTEM fflush (stdout); fflush (stderr); #endif if (fflush (NULL)) { #ifndef HAVE_W32_SYSTEM gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); #endif log_error ("error flushing pending output: %s\n", strerror (errno)); /* At least Windows XP fails here with EBADF. According to docs and Wine an fflush(NULL) is the same as _flushall. However the Wime implementaion does not flush stdin,stdout and stderr - see above. Lets try to ignore the error. */ #ifndef HAVE_W32_SYSTEM return unlock_pinentry (tmperr); #endif } if (!opt.pinentry_program || !*opt.pinentry_program) opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); pgmname = opt.pinentry_program; if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) pgmname = opt.pinentry_program; else pgmname++; /* OS X needs the entire file name in argv[0], so that it can locate the resource bundle. For other systems we stick to the usual convention of supplying only the name of the program. */ #ifdef __APPLE__ argv[0] = opt.pinentry_program; #else /*!__APPLE__*/ argv[0] = pgmname; #endif /*__APPLE__*/ if (!opt.keep_display && (value = session_env_getenv (ctrl->session_env, "DISPLAY"))) { argv[1] = "--display"; argv[2] = value; argv[3] = NULL; } else argv[1] = NULL; i=0; if (!opt.running_detached) { if (log_get_fd () != -1) no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); } no_close_list[i] = -1; rc = assuan_new (&ctx); if (rc) { log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); return rc; } /* Connect to the pinentry and perform initial handshaking. Note that atfork is used to change the environment for pinentry. We start the server in detached mode to suppress the console window under Windows. */ rc = assuan_pipe_connect (ctx, opt.pinentry_program, argv, no_close_list, atfork_cb, ctrl, ASSUAN_PIPE_CONNECT_DETACHED); if (rc) { log_error ("can't connect to the PIN entry module: %s\n", gpg_strerror (rc)); assuan_release (ctx); return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY)); } entry_ctx = ctx; if (DBG_ASSUAN) log_debug ("connection to PIN entry established\n"); rc = assuan_transact (entry_ctx, opt.no_grab? "OPTION no-grab":"OPTION grab", NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return unlock_pinentry (rc); value = session_env_getenv (ctrl->session_env, "GPG_TTY"); if (value) { char *optstr; if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); if (rc) return unlock_pinentry (rc); } value = session_env_getenv (ctrl->session_env, "TERM"); if (value) { char *optstr; if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); if (rc) return unlock_pinentry (rc); } if (ctrl->lc_ctype) { char *optstr; if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); if (rc) return unlock_pinentry (rc); } if (ctrl->lc_messages) { char *optstr; if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); if (rc) return unlock_pinentry (rc); } { /* Provide a few default strings for use by the pinentries. This may help a pinentry to avoid implementing localization code. */ static struct { const char *key, *value; } tbl[] = { /* TRANSLATORS: These are labels for buttons etc used in Pinentries. An underscore indicates that the next letter should be used as an accelerator. Double the underscore for a literal one. The actual to be translated text starts after the second vertical bar. */ { "ok", N_("|pinentry-label|_OK") }, { "cancel", N_("|pinentry-label|_Cancel") }, { "prompt", N_("|pinentry-label|PIN:") }, { NULL, NULL} }; char *optstr; int idx; const char *s, *s2; for (idx=0; tbl[idx].key; idx++) { s = _(tbl[idx].value); if (*s == '|' && (s2=strchr (s+1,'|'))) s = s2+1; if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 ) return unlock_pinentry (out_of_core ()); assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); } } /* Tell the pinentry the name of a file it shall touch after having messed with the tty. This is optional and only supported by newer pinentries and thus we do no error checking. */ tmpstr = opt.pinentry_touch_file; if (tmpstr && !strcmp (tmpstr, "/dev/null")) tmpstr = NULL; else if (!tmpstr) tmpstr = get_agent_socket_name (); if (tmpstr) { char *optstr; if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 ) ; else { assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); xfree (optstr); } } /* Now ask the Pinentry for its PID. If the Pinentry is new enough it will send the pid back and we will use an inquire to notify our client. The client may answer the inquiry either with END or with CAN to cancel the pinentry. */ rc = assuan_transact (entry_ctx, "GETINFO pid", getinfo_pid_cb, &pinentry_pid, NULL, NULL, NULL, NULL); if (rc) { log_info ("You may want to update to a newer pinentry\n"); rc = 0; } else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1)) log_error ("pinentry did not return a PID\n"); else { rc = agent_inq_pinentry_launched (ctrl, pinentry_pid); if (gpg_err_code (rc) == GPG_ERR_CANCELED) return unlock_pinentry (gpg_error (GPG_ERR_CANCELED)); rc = 0; } return 0; }
int main(int argc, char *argv[]) { if (argc < 5) { return 1; } auto processNum = 4; auto threadNum = atoi(argv[4]); auto dtime = atol(argv[3]) * 1000; auto isPth = std::string(argv[2]) == "pth"; auto taskNum = atoi(argv[1]); long cycles = 0; switch(taskNum) { case 1: task = task1; break; case 2: task = task2; break; case 3: task = task3; break; } time_start(); for (auto i = 0; i < processNum; ++i) { if (fork() != 0) { continue; } if (isPth) { pth_init(); pth_attr_t attr = pth_attr_new(); pth_attr_set(attr, PTH_ATTR_NAME, "task"); pth_attr_set(attr, PTH_ATTR_STACK_SIZE, 64*1024); pth_attr_set(attr, PTH_ATTR_JOINABLE, true); pth_mutex_t mutex; pth_mutex_init(&mutex); pth_cond_init(&pthCond); while (time_stop() < dtime) { for (auto i = workingNum; i < threadNum; ++i) { ++workingNum; pth_spawn(attr, task, &isPth); } int rc; if ((rc = pth_mutex_acquire(&mutex, FALSE, NULL)) != 0) { std::cout << "pthread_mutex_lock " << rc << " " << strerror(rc) << std::endl; return 3; } if (workingNum == threadNum) { if ((rc = pth_cond_await(&pthCond, &mutex, NULL)) != 0) { std::cout << "pthread_cond_wait " << rc << " " << strerror(rc) << std::endl; return 3; } } if ((rc = pth_mutex_release(&mutex)) != 0) { std::cout << "pthread_mutex_unlock " << rc << " " << strerror(rc) << std::endl; return 3; } cycles += threadNum - workingNum; } } else { pthread_attr_t attr; pthread_attr_setstacksize(&attr, 64*1024); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutexattr_t mutexattr; pthread_mutex_init(&mutex, &mutexattr); pthread_condattr_t condattr; pthread_cond_init(&cond, &condattr); pthread_t pid; while (time_stop() < dtime) { for (auto i = workingNum; i < threadNum; ++i) { ++workingNum; if (pthread_create(&pid, NULL, task, &isPth) == -1) { return 2; } } int rc; if ((rc = pthread_mutex_lock(&mutex)) != 0) { std::cout << "pthread_mutex_lock " << rc << " " << strerror(rc) << std::endl; return 3; } if (workingNum == threadNum) { if ((rc = pthread_cond_wait(&cond, &mutex)) != 0) { std::cout << "pthread_cond_wait " << rc << " " << strerror(rc) << std::endl; return 3; } } if ((rc = pthread_mutex_unlock(&mutex)) != 0) { std::cout << "pthread_mutex_unlock " << rc << " " << strerror(rc) << std::endl; return 3; } //pthread_join(pids.front(), NULL); //pids.pop_front(); cycles += threadNum - workingNum; } } std::cout << cycles << std::endl; return 0; } for (auto i = 0; i < processNum; ++i) { wait(NULL); } return 0; }