Example #1
0
/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
	void*	exit_value)	/*!< in: exit value; in Windows this void*
				is cast as a DWORD */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
	fprintf(stderr, "Thread exits, id %lu\n",
		os_thread_pf(os_thread_get_curr_id()));
#endif

#ifdef UNIV_PFS_THREAD
	pfs_delete_thread();
#endif

	os_mutex_enter(os_sync_mutex);
	os_thread_count--;
	os_mutex_exit(os_sync_mutex);

#ifdef __WIN__
	ExitThread((DWORD)exit_value);
#else
	pthread_detach(pthread_self());
	pthread_exit(exit_value);
#endif
}
Example #2
0
/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_mutex_free(
/*==========*/
	os_mutex_t	mutex)	/*!< in: mutex to free */
{
	ut_a(mutex);

	if (UNIV_LIKELY(!os_sync_free_called)) {
		os_event_free_internal(mutex->event);
	}

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		os_mutex_enter(os_sync_mutex);
	}

	UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);

	os_mutex_count--;

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		os_mutex_exit(os_sync_mutex);
	}

#ifdef __WIN__
	ut_a(CloseHandle(mutex->handle));

	ut_free(mutex);
#else
	os_fast_mutex_free(mutex->handle);
	ut_free(mutex->handle);
	ut_free(mutex);
#endif
}
Example #3
0
/*********************************************************//**
Initializes an operating system fast mutex semaphore. */
UNIV_INTERN
void
os_fast_mutex_init(
/*===============*/
	os_fast_mutex_t*	fast_mutex)	/*!< in: fast mutex */
{
#ifdef __WIN__
	ut_a(fast_mutex);

	InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
	ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
#endif
	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		/* When creating os_sync_mutex itself (in Unix) we cannot
		reserve it */

		os_mutex_enter(os_sync_mutex);
	}

	os_fast_mutex_count++;

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		os_mutex_exit(os_sync_mutex);
	}
}
Example #4
0
/**********************************************************//**
Frees an event object. */
UNIV_INTERN
void
os_event_free(
/*==========*/
	os_event_t	event)	/*!< in: event to free */

{
#ifdef __WIN__
	ut_a(event);

	ut_a(CloseHandle(event->handle));
#else
	ut_a(event);

	os_fast_mutex_free(&(event->os_mutex));
	ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
#endif
	/* Remove from the list of events */

	os_mutex_enter(os_sync_mutex);

	UT_LIST_REMOVE(os_event_list, os_event_list, event);

	os_event_count--;

	os_mutex_exit(os_sync_mutex);

	ut_free(event);
}
Example #5
0
/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
	void*	exit_value)	/*!< in: exit value; in Windows this void*
				is cast as a DWORD */
{
#ifndef __WIN__
	int	ret;
#endif /* __WIN__ */

#ifdef UNIV_DEBUG_THREAD_CREATION
	ib_logger(ib_stream, "Thread exits, id %lu\n",
		os_thread_pf(os_thread_get_curr_id()));
#endif /* UNIV_DEBUG_THREAD_CREATION */

	os_mutex_enter(os_sync_mutex);
	os_thread_count--;
	os_mutex_exit(os_sync_mutex);

#ifdef __WIN__
	ExitThread((DWORD)exit_value);
#else
	ret = pthread_detach(pthread_self());
	ut_a(ret == 0);

	pthread_exit(exit_value);
#endif /* __WIN__ */
}
Example #6
0
/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
@return	the mutex handle */
UNIV_INTERN
os_mutex_t
os_mutex_create(
/*============*/
	const char*	name)	/*!< in: the name of the mutex, if NULL
				the mutex is created without a name */
{
#ifdef __WIN__
	HANDLE		mutex;
	os_mutex_t	mutex_str;

	mutex = CreateMutex(NULL,	/* No security attributes */
			    FALSE,		/* Initial state: no owner */
			    (LPCTSTR) name);
	ut_a(mutex);
#else
	os_fast_mutex_t*	mutex;
	os_mutex_t		mutex_str;

	UT_NOT_USED(name);

	mutex = ut_malloc(sizeof(os_fast_mutex_t));

	os_fast_mutex_init(mutex);
#endif
	mutex_str = ut_malloc(sizeof(os_mutex_str_t));

	mutex_str->handle = mutex;
	mutex_str->count = 0;
	mutex_str->event = os_event_create(NULL);

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		/* When creating os_sync_mutex itself we cannot reserve it */
		os_mutex_enter(os_sync_mutex);
	}

	UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);

	os_mutex_count++;

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		os_mutex_exit(os_sync_mutex);
	}

	return(mutex_str);
}
Example #7
0
/******************************************************************//**
Releases the mutex semaphore protecting a sync array. */
static
void
sync_array_exit(
/*============*/
	sync_array_t*	arr)	/*!< in: sync wait array */
{
	ulint	protection;

	protection = arr->protection;

	if (protection == SYNC_ARRAY_OS_MUTEX) {
		os_mutex_exit(arr->os_mutex);
	} else if (protection == SYNC_ARRAY_MUTEX) {
		mutex_exit(&(arr->mutex));
	} else {
		ut_error;
	}
}
Example #8
0
/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_fast_mutex_free(
/*===============*/
	os_fast_mutex_t*	fast_mutex)	/*!< in: mutex to free */
{
#ifdef __WIN__
	ut_a(fast_mutex);

	DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
	int	ret;

	ret = pthread_mutex_destroy(fast_mutex);

	if (UNIV_UNLIKELY(ret != 0)) {
		ut_print_timestamp(stderr);
		fprintf(stderr,
			"  InnoDB: error: return value %lu when calling\n"
			"InnoDB: pthread_mutex_destroy().\n", (ulint)ret);
		fprintf(stderr,
			"InnoDB: Byte contents of the pthread mutex at %p:\n",
			(void*) fast_mutex);
		ut_print_buf(stderr, fast_mutex, sizeof(os_fast_mutex_t));
		putc('\n', stderr);
	}
#endif
	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		/* When freeing the last mutexes, we have
		already freed os_sync_mutex */

		os_mutex_enter(os_sync_mutex);
	}

	ut_ad(os_fast_mutex_count > 0);
	os_fast_mutex_count--;

	if (UNIV_LIKELY(os_sync_mutex_inited)) {
		os_mutex_exit(os_sync_mutex);
	}
}
Example #9
0
/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
and returns an ulint.
@return	handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
#ifndef __WIN__
	os_posix_f_t		start_f,
#else
	ulint (*start_f)(void*),		/*!< in: pointer to function
						from which to start */
#endif
	void*			arg,		/*!< in: argument to start
						function */
	os_thread_id_t*		thread_id)	/*!< out: id of the created
						thread, or NULL */
{
#ifdef __WIN__
	os_thread_t	thread;
	DWORD		win_thread_id;

	os_mutex_enter(os_sync_mutex);
	os_thread_count++;
	os_mutex_exit(os_sync_mutex);

	thread = CreateThread(NULL,	/* no security attributes */
			      0,	/* default size stack */
			      (LPTHREAD_START_ROUTINE)start_f,
			      arg,
			      0,	/* thread runs immediately */
			      &win_thread_id);

	if (thread_id) {
		*thread_id = win_thread_id;
	}

	return(thread);
#else
	int		ret;
	os_thread_t	pthread;
	pthread_attr_t	attr;

#ifndef UNIV_HPUX10
	pthread_attr_init(&attr);
#endif

#ifdef UNIV_AIX
	/* We must make sure a thread stack is at least 32 kB, otherwise
	InnoDB might crash; we do not know if the default stack size on
	AIX is always big enough. An empirical test on AIX-4.3 suggested
	the size was 96 kB, though. */

	ret = pthread_attr_setstacksize(&attr,
					(size_t)(PTHREAD_STACK_MIN
						 + 32 * 1024));
	if (ret) {
		fprintf(stderr,
			"InnoDB: Error: pthread_attr_setstacksize"
			" returned %d\n", ret);
		exit(1);
	}
#endif
	os_mutex_enter(os_sync_mutex);
	os_thread_count++;
	os_mutex_exit(os_sync_mutex);

#ifdef UNIV_HPUX10
	ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
#else
	ret = pthread_create(&pthread, &attr, start_f, arg);
#endif
	if (ret) {
		fprintf(stderr,
			"InnoDB: Error: pthread_create returned %d\n", ret);
		exit(1);
	}

#ifndef UNIV_HPUX10
	pthread_attr_destroy(&attr);
#endif
	if (thread_id) {
		*thread_id = pthread;
	}

	return(pthread);
#endif
}
Example #10
0
/*********************************************************//**
Creates an event semaphore, i.e., a semaphore which may just have two
states: signaled and nonsignaled. The created event is manual reset: it
must be reset explicitly by calling sync_os_reset_event.
@return	the event handle */
UNIV_INTERN
os_event_t
os_event_create(
/*============*/
	const char*	name)	/*!< in: the name of the event, if NULL
				the event is created without a name */
{
#ifdef __WIN__
	os_event_t event;

	event = ut_malloc(sizeof(struct os_event_struct));

	event->handle = CreateEvent(NULL, /* No security attributes */
				    TRUE, /* Manual reset */
				    FALSE, /* Initial state nonsignaled */
				    (LPCTSTR) name);
	if (!event->handle) {
		fprintf(stderr,
			"InnoDB: Could not create a Windows event semaphore;"
			" Windows error %lu\n",
			(ulong) GetLastError());
	}
#else /* Unix */
	os_event_t	event;

	UT_NOT_USED(name);

	event = ut_malloc(sizeof(struct os_event_struct));

	os_fast_mutex_init(&(event->os_mutex));

	ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));

	event->is_set = FALSE;

	/* We return this value in os_event_reset(), which can then be
	be used to pass to the os_event_wait_low(). The value of zero
	is reserved in os_event_wait_low() for the case when the
	caller does not want to pass any signal_count value. To
	distinguish between the two cases we initialize signal_count
	to 1 here. */
	event->signal_count = 1;
#endif /* __WIN__ */

	/* The os_sync_mutex can be NULL because during startup an event
	can be created [ because it's embedded in the mutex/rwlock ] before
	this module has been initialized */
	if (os_sync_mutex != NULL) {
		os_mutex_enter(os_sync_mutex);
	}

	/* Put to the list of events */
	UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);

	os_event_count++;

	if (os_sync_mutex != NULL) {
		os_mutex_exit(os_sync_mutex);
	}

	return(event);
}
Example #11
0
/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
and returns an ulint.
@return	handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
#ifndef __WIN__
	os_posix_f_t		start_f,
#else
	ulint (*start_f)(void*),		/*!< in: pointer to function
						from which to start */
#endif
	void*			arg,		/*!< in: argument to start
						function */
	os_thread_id_t*		thread_id)	/*!< out: id of the created
						thread, or NULL */
{
#ifdef __WIN__
	os_thread_t	thread;
	DWORD		win_thread_id;

	os_mutex_enter(os_sync_mutex);
	os_thread_count++;
	os_mutex_exit(os_sync_mutex);

	thread = CreateThread(NULL,	/* no security attributes */
			      0,	/* default size stack */
			      (LPTHREAD_START_ROUTINE)start_f,
			      arg,
			      0,	/* thread runs immediately */
			      &win_thread_id);

	if (srv_set_thread_priorities) {

		/* Set created thread priority the same as a normal query,
		we try to prevent starvation of threads by assigning same
		priority QUERY_PRIOR to all */

		ut_a(SetThreadPriority(thread, srv_query_thread_priority));
	}

	if (thread_id) {
		*thread_id = win_thread_id;
	}

	return(thread);
#else
	int		ret;
	os_thread_t	pthread;
	pthread_attr_t	attr;

#ifndef UNIV_HPUX10
	pthread_attr_init(&attr);
#endif

#ifdef UNIV_AIX
	/* We must make sure a thread stack is at least 32 kB, otherwise
	InnoDB might crash; we do not know if the default stack size on
	AIX is always big enough. An empirical test on AIX-4.3 suggested
	the size was 96 kB, though. */

	ret = pthread_attr_setstacksize(&attr,
					(size_t)(PTHREAD_STACK_MIN
						 + 32 * 1024));
	if (ret) {
		srv_panic(ret,
			"InnoDB: Error: pthread_attr_setstacksize"
			" returned %d\n", ret);
	}
#endif
#ifdef __NETWARE__
	ret = pthread_attr_setstacksize(&attr,
					(size_t) NW_THD_STACKSIZE);
	if (ret) {
		srv_panic(ret,
			"InnoDB: Error: pthread_attr_setstacksize"
			" returned %d\n", ret);
	}
#endif
	os_mutex_enter(os_sync_mutex);
	os_thread_count++;
	os_mutex_exit(os_sync_mutex);

#ifdef UNIV_HPUX10
	ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
#else
	ret = pthread_create(&pthread, &attr, start_f, arg);
#endif
	if (ret) {
		srv_panic(ret,
			"InnoDB: Error: pthread_create returned %d\n", ret);
	}

#ifndef UNIV_HPUX10
	pthread_attr_destroy(&attr);
#endif
	if (srv_set_thread_priorities) {

#ifdef HAVE_PTHREAD_SETPRIO 
		pthread_setprio(pthread, srv_query_thread_priority);
#endif
	}

	if (thread_id) {
		*thread_id = pthread;
	}

	return(pthread);
#endif
}