Exemple #1
0
/*	===== monitoring ===============================================================
	PRIVATE. Check in the thread entries list to detect ended threads.
	These threads see their entry deleted.
	================================================================================	*/
int32 monitoring (void* unused)
	{
	int i ;
	int numberDeleted ;
	thread_info info ;
	_tls_thread_entry_t* pEntry ;

	//	We use semaphore time-outs to periodically wake up the monitoring thread,
	//	with acquire_sem_etc returning B_TIMED_OUT.
	//	When the term function is called, it set the semaphore and the thread
	//	is immediatly resumed with acquire_sem_etc returning B_NO_ERROR.
	while (acquire_sem_etc (gm_signalExit, 1, B_TIMEOUT, 1000000LL) == B_TIMED_OUT)
		{
		//	Must be reset at each iteration (ex-bug).
		numberDeleted = 0 ;
		tls_entries_mutex_p () ;
			{
			for (i=0 ; i<gm_entries_count ; i++)
				{
				pEntry = gm_sorted[i] ;
				//	If not used, continue...
				if (pEntry->sign == SIGN_FREE) continue ;
				//	Get thread info. If impossible... the thread should be down.
				if (B_NO_ERROR != get_thread_info (pEntry->ownerThread, &info))
					{
					//	As the entry is to be deleted, call the TLS exit procs.
					tls_call_entry_exit (pEntry->ownerThread, PROC_EXIT, pEntry) ;
					//	Simply note it as free.
					pEntry->sign = SIGN_FREE ;
					numberDeleted++ ;
					}
				}
			//	Update globals.
			if (numberDeleted != 0)
				{
				//	Sort-it so deleted be moved at the end of the sorted array.
				assert (gm_sorted != NULL) ;
				assert (gm_entries_count >= 0) ;
				qsort (gm_sorted, gm_entries_count, sizeof (_tls_thread_entry_t*), 
						qsort_comp_proc) ;
				//	And decrement the number of elements.
				gm_entries_count -= numberDeleted ;
				}
			}
		tls_entries_mutex_v () ;
		}
	return 0 ;
	}
Exemple #2
0
/*	===== tls_delete_entry =========================================================
	PRIVATE. Delete an entry by its entry address.
	================================================================================	*/
status_t tls_delete_entry (_tls_thread_entry_t* pEntry)
	{
	//	Internal check - must never occur.
	assert (pEntry != NULL) ;
	//	As the entry is deleted, call the TLS exit procs.
	tls_call_entry_exit (pEntry->ownerThread, PROC_EXIT, pEntry) ;
	//	Simply note it as free.
	pEntry->sign = SIGN_FREE ;
	//	Sort-it so it be moved at the end of the sorted array.
	assert (gm_sorted != NULL) ;
	assert (gm_entries_count >= 0) ;
	qsort (gm_sorted, gm_entries_count, sizeof (_tls_thread_entry_t*), qsort_comp_proc) ;
	//	And decrement the number of elements.
	gm_entries_count-- ;

	return B_NO_ERROR ;
	}
Exemple #3
0
/*	===== tls_create_entry =========================================================
	PRIVATE. Create an entry for a thread.
	================================================================================	*/
status_t tls_create_entry (thread_id id, _tls_thread_entry_t** ppEntry) 
	{
	_tls_thread_entry_t* pEntry = NULL ;
	status_t status ;
	int i ;

	//	Check parameters.
	if (id < 0) return B_BAD_VALUE ;
	if (ppEntry == NULL) return B_BAD_VALUE ;

	//	Set to NULL so that a use without error checking will resolve into error too.
	*ppEntry = NULL ;

	//	If no more room, reallocate more entries.
	if (gm_entries_count == gm_entries_allocated_count)
		{
		if ((status = tls_expand_entries (THREAD_ENTRIES_ADD_COUNT)) != B_NO_ERROR) 
			return status ;
		}

	//	Use next entry in the sorted array.
	//	If data remain associated with the entry, erase it.
	pEntry = gm_sorted[gm_entries_count] ;
	pEntry->sign = SIGN_OK ;
	pEntry->ownerThread = id ;
	if (pEntry->datasCount)
		{
		for (i=0 ; i<pEntry->datasCount ; i++)
			pEntry->datas[i] = 0 ;
		}
	gm_entries_count++ ;

	//	Sort the array with the new entry.
	assert (gm_sorted != NULL) ;
	assert (gm_entries_count >= 0) ;
	qsort (gm_sorted, gm_entries_count, sizeof (_tls_thread_entry_t*), qsort_comp_proc) ;

	//	As a new entry is created for this thread, call the TLS entry procs.
	tls_call_entry_exit (id, PROC_ENTRY, pEntry) ;

	//	Finish.
	*ppEntry = pEntry ;
	return B_NO_ERROR ;
	}
Exemple #4
0
/*	===== tls_entering_procs =======================================================
	PUBLIC. 
	================================================================================	*/
status_t tls_entering_procs ()
	{
	thread_id id = find_thread (NULL) ;
	_tls_thread_entry_t* e = NULL ;
	status_t status ;
	bool newlyCreated = false ;

	//	Search for the thread entry.
	//	If not founded, create it and dont call entry procs because tls_create_entry
	//	automatically call them.
	//	If founded, call entry procs.
	if ((status = tls_entries_mutex_p ()) == B_NO_ERROR)
		{
		if ((status = tls_get_entry (id, &e)) != B_NO_ERROR)
			status = tls_create_entry (id, &e) ;
		else
			tls_call_entry_exit (id, PROC_ENTRY, e) ;
		tls_entries_mutex_v () ;
		}
	if (status != B_NO_ERROR) return status ;
	
	//	Finish
	return B_NO_ERROR ;
	}