void semaphore_leave (semaphore_t *sem) #endif { thread_t *thr; int rc; rc = pthread_mutex_lock ((pthread_mutex_t*) sem->sem_handle); CKRET (rc); #ifdef SEM_DEBUG { int inx; if (304 == ln && sem->sem_entry_count) GPF_T1 ("should have 0 count when signalling clrg_wait"); for (inx = MAX_SEM_ENT - 1; inx > 0; inx--) { sem->sem_last_left_line[inx] = sem->sem_last_left_line[inx - 1]; sem->sem_last_left_file[inx] = sem->sem_last_left_file[inx - 1]; } sem->sem_last_left_line[0] = ln; sem->sem_last_left_file[0] = file; } #endif if (sem->sem_entry_count) sem->sem_entry_count++; else { #ifndef SEM_NO_ORDER thr = thread_queue_from (&sem->sem_waiting); if (thr) { _thread_num_wait--; assert (thr->thr_status == WAITSEM); thr->thr_status = RUNNING; pthread_cond_signal ((pthread_cond_t *) thr->thr_cv); } else sem->sem_entry_count++; #else if (sem->sem_waiting.thq_count) { _thread_num_wait--; sem->sem_any_signalled = 1; pthread_cond_signal ((pthread_cond_t *) sem->sem_cv); } else sem->sem_entry_count++; #endif } rc = pthread_mutex_unlock ((pthread_mutex_t*) sem->sem_handle); CKRET (rc); return; failed: GPF_T1 ("semaphore_leave() failed"); }
void semaphore_free (semaphore_t *sem) { thread_t *thr; while ((thr = thread_queue_from (&sem->sem_waiting)) != NULL) _fiber_status (thr, RUNNABLE); dk_free (sem, sizeof (semaphore_t)); }
int thread_release_dead_threads (int leave_count) { thread_t *thr; int rc; long thread_killed = 0; thread_queue_t term; Q_LOCK (); if (_deadq.thq_count <= leave_count) { Q_UNLOCK (); return 0; } thread_queue_init (&term); while (_deadq.thq_count > leave_count) { thr = thread_queue_from (&_deadq); if (!thr) break; _thread_num_dead--; thread_queue_to (&term, thr); } Q_UNLOCK (); while (NULL != (thr = thread_queue_from (&term))) { thr->thr_status = TERMINATE; rc = pthread_cond_signal ((pthread_cond_t *) thr->thr_cv); CKRET (rc); thread_killed++; } #if 0 if (thread_killed) log_info ("%ld OS threads released", thread_killed); #endif return thread_killed; failed: GPF_T1("Thread restart failed"); return 0; }
DK_INLINE void semaphore_leave (semaphore_t *sem) #endif { thread_t *thr; if (sem->sem_entry_count) sem->sem_entry_count++; else { thr = thread_queue_from (&sem->sem_waiting); if (thr) { assert (thr->thr_status == WAITSEM); _fiber_status (thr, RUNNABLE); } else sem->sem_entry_count++; } }
void mutex_leave (dk_mutex_t *mtx) #endif { #ifndef MTX_DEBUG semaphore_leave (mtx->mtx_handle); #else semaphore_t *sem = (semaphore_t *) mtx->mtx_handle; thread_t *thr; #ifdef MALLOC_DEBUG if (_current_fiber == NULL) { assert (mtx == _dbgmal_mtx); semaphore_leave (sem); return; } #endif assert (mtx->mtx_owner == _current_fiber); assert (sem->sem_entry_count == 0); mtx->mtx_owner = NULL; if (sem->sem_entry_count) sem->sem_entry_count++; else { thr = thread_queue_from (&sem->sem_waiting); if (thr) { assert (thr->thr_status == WAITSEM); _fiber_status (thr, RUNNABLE); } else sem->sem_entry_count++; } #endif }