示例#1
0
文件: ut0dbg.c 项目: AllenWeb/mariadb
/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
void
ut_dbg_assertion_failed(
/*====================*/
	const char* expr,	/*!< in: the failed assertion (optional) */
	const char* file,	/*!< in: source file containing the assertion */
	ulint line)		/*!< in: line number of the assertion */
{
	ut_print_timestamp(stderr);
#ifdef UNIV_HOTBACKUP
	fprintf(stderr, "  InnoDB: Assertion failure in file %s line %lu\n",
		file, line);
#else /* UNIV_HOTBACKUP */
	fprintf(stderr,
		"  InnoDB: Assertion failure in thread %lu"
		" in file %s line %lu\n",
		os_thread_pf(os_thread_get_curr_id()),
		innobase_basename(file), line);
#endif /* UNIV_HOTBACKUP */
	if (expr) {
		fprintf(stderr,
			"InnoDB: Failing assertion: %s\n", expr);
	}

	fputs("InnoDB: We intentionally generate a memory trap.\n"
	      "InnoDB: Submit a detailed bug report"
	      " to http://bugs.mysql.com.\n"
	      "InnoDB: If you get repeated assertion failures"
	      " or crashes, even\n"
	      "InnoDB: immediately after the mysqld startup, there may be\n"
	      "InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
	      "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
	      "InnoDB: about forcing recovery.\n", stderr);
}
示例#2
0
文件: sync0arr.c 项目: 0x00xw/mysql-2
/******************************************************************//**
Reports info of a wait array cell. */
static
void
sync_array_cell_print(
/*==================*/
	FILE*		file,	/*!< in: file where to print */
	sync_cell_t*	cell)	/*!< in: sync cell */
{
	mutex_t*	mutex;
	rw_lock_t*	rwlock;
	ulint		type;
	ulint		writer;

	type = cell->request_type;

	fprintf(file,
		"--Thread %lu has waited at %s line %lu"
		" for %.2f seconds the semaphore:\n",
		(ulong) os_thread_pf(cell->thread),
		innobase_basename(cell->file), (ulong) cell->line,
		difftime(time(NULL), cell->reservation_time));

	if (type == SYNC_MUTEX) {
		/* We use old_wait_mutex in case the cell has already
		been freed meanwhile */
		mutex = cell->old_wait_mutex;

		fprintf(file,
			"Mutex at %p created file %s line %lu, lock var %lu\n"
#ifdef UNIV_SYNC_DEBUG
			"Last time reserved in file %s line %lu, "
#endif /* UNIV_SYNC_DEBUG */
			"waiters flag %lu\n",
			(void*) mutex, innobase_basename(mutex->cfile_name),
			(ulong) mutex->cline,
			(ulong) mutex->lock_word,
#ifdef UNIV_SYNC_DEBUG
			mutex->file_name, (ulong) mutex->line,
#endif /* UNIV_SYNC_DEBUG */
			(ulong) mutex->waiters);

	} else if (type == RW_LOCK_EX
		   || type == RW_LOCK_WAIT_EX
		   || type == RW_LOCK_SHARED) {

		fputs(type == RW_LOCK_EX ? "X-lock on"
		      : type == RW_LOCK_WAIT_EX ? "X-lock (wait_ex) on"
		      : "S-lock on", file);

		rwlock = cell->old_wait_rw_lock;

		fprintf(file,
			" RW-latch at %p created in file %s line %lu\n",
			(void*) rwlock, innobase_basename(rwlock->cfile_name),
			(ulong) rwlock->cline);
		writer = rw_lock_get_writer(rwlock);
		if (writer != RW_LOCK_NOT_LOCKED) {
			fprintf(file,
				"a writer (thread id %lu) has"
				" reserved it in mode %s",
				(ulong) os_thread_pf(rwlock->writer_thread),
				writer == RW_LOCK_EX
				? " exclusive\n"
				: " wait exclusive\n");
		}

		fprintf(file,
			"number of readers %lu, waiters flag %lu, "
                        "lock_word: %lx\n"
			"Last time read locked in file %s line %lu\n"
			"Last time write locked in file %s line %lu\n",
			(ulong) rw_lock_get_reader_count(rwlock),
			(ulong) rwlock->waiters,
			rwlock->lock_word,
			innobase_basename(rwlock->last_s_file_name),
			(ulong) rwlock->last_s_line,
			rwlock->last_x_file_name,
			(ulong) rwlock->last_x_line);
	} else {
		ut_error;
	}

	if (!cell->waiting) {
		fputs("wait has ended\n", file);
	}
}
示例#3
0
/***************************************************************//**
Removes a memory heap (which is going to be freed by the caller)
from the list of live memory heaps. Returns the size of the heap
in terms of how much memory in bytes was allocated for the user of
the heap (not the total space occupied by the heap).
Also validates the heap.
NOTE: This function does not free the storage occupied by the
heap itself, only the node in the list of heaps. */
UNIV_INTERN
void
mem_hash_remove(
/*============*/
	mem_heap_t*	heap,	   /*!< in: the heap to be freed */
	const char*	file_name, /*!< in: file name of freeing */
	ulint		line)	   /*!< in: line where freed */
{
	mem_hash_node_t*	node;
	ulint			cell_no;
	ibool			error;
	ulint			size;

	ut_ad(mem_heap_check(heap));

	mutex_enter(&mem_hash_mutex);

	cell_no = ut_hash_ulint((ulint)heap, MEM_HASH_SIZE);

	/* Look for the heap in the hash table list */
	node = UT_LIST_GET_FIRST(*mem_hash_get_nth_cell(cell_no));

	while (node != NULL) {
		if (node->heap == heap) {

			break;
		}

		node = UT_LIST_GET_NEXT(list, node);
	}

	if (node == NULL) {
		fprintf(stderr,
			"Memory heap or buffer freed in %s line %lu"
			" did not exist.\n",
			innobase_basename(file_name), (ulong) line);
		ut_error;
	}

	/* Remove from lists */
	UT_LIST_REMOVE(list, *mem_hash_get_nth_cell(cell_no), node);

	UT_LIST_REMOVE(all_list, mem_all_list_base, node);

	/* Validate the heap which will be freed */
	mem_heap_validate_or_print(node->heap, NULL, FALSE, &error, &size,
				   NULL, NULL);
	if (error) {
		fprintf(stderr,
			"Inconsistency in memory heap or"
			" buffer n:o %lu created\n"
			"in %s line %lu and tried to free in %s line %lu.\n"
			"Hex dump of 400 bytes around memory heap"
			" first block start:\n",
			node->nth_heap,
			innobase_basename(node->file_name), (ulong) node->line,
			innobase_basename(file_name), (ulong) line);
		ut_print_buf(stderr, (byte*)node->heap - 200, 400);
		fputs("\nDump of the mem heap:\n", stderr);
		mem_heap_validate_or_print(node->heap, NULL, TRUE, &error,
					   &size, NULL, NULL);
		ut_error;
	}

	/* Free the memory occupied by the node struct */
	ut_free(node);

	mem_current_allocated_memory -= size;

	mutex_exit(&mem_hash_mutex);
}
示例#4
0
文件: sync0rw.c 项目: A-eolus/mysql
/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
in shared or exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
for the lock before suspending the thread. If the same thread has an x-lock
on the rw-lock, locking succeed, with the following exception: if pass != 0,
only a single x-lock may be taken on the lock. NOTE: If the same thread has
an s-lock, locking does not succeed! */
UNIV_INTERN
void
rw_lock_x_lock_func(
/*================*/
	rw_lock_t*	lock,	/*!< in: pointer to rw-lock */
	ulint		pass,	/*!< in: pass value; != 0, if the lock will
				be passed to another thread to unlock */
	const char*	file_name,/*!< in: file name where lock requested */
	ulint		line)	/*!< in: line where requested */
{
	ulint	index;	/*!< index of the reserved wait cell */
	ulint	i;	/*!< spin round count */
	ibool	spinning = FALSE;

	ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_DEBUG
	ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */

	i = 0;

lock_loop:

	if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
		rw_x_spin_round_count += i;

		return;	/* Locking succeeded */

	} else {

                if (!spinning) {
                        spinning = TRUE;
                        rw_x_spin_wait_count++;
		}

		/* Spin waiting for the lock_word to become free */
		while (i < SYNC_SPIN_ROUNDS
		       && lock->lock_word <= 0) {
			if (srv_spin_wait_delay) {
				ut_delay(ut_rnd_interval(0,
							 srv_spin_wait_delay));
			}

			i++;
		}
		if (i == SYNC_SPIN_ROUNDS) {
			os_thread_yield();
		} else {
			goto lock_loop;
		}
	}

	rw_x_spin_round_count += i;

	if (srv_print_latch_waits) {
		fprintf(stderr,
			"Thread %lu spin wait rw-x-lock at %p"
			" cfile %s cline %lu rnds %lu\n",
			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
			innobase_basename(lock->cfile_name),
			(ulong) lock->cline, (ulong) i);
	}

	sync_array_reserve_cell(sync_primary_wait_array,
				lock,
				RW_LOCK_EX,
				file_name, line,
				&index);

	/* Waiters must be set before checking lock_word, to ensure signal
	is sent. This could lead to a few unnecessary wake-up signals. */
	rw_lock_set_waiter_flag(lock);

	if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
		sync_array_free_cell(sync_primary_wait_array, index);
		return; /* Locking succeeded */
	}

	if (srv_print_latch_waits) {
		fprintf(stderr,
			"Thread %lu OS wait for rw-x-lock at %p"
			" cfile %s cline %lu\n",
			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
			innobase_basename(lock->cfile_name),
			(ulong) lock->cline);
	}

	/* these stats may not be accurate */
	lock->count_os_wait++;
	rw_x_os_wait_count++;

	sync_array_wait_event(sync_primary_wait_array, index);

	i = 0;
	goto lock_loop;
}
示例#5
0
文件: sync0rw.c 项目: A-eolus/mysql
/******************************************************************//**
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
locked in exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
for the lock, before suspending the thread. */
UNIV_INTERN
void
rw_lock_s_lock_spin(
/*================*/
	rw_lock_t*	lock,	/*!< in: pointer to rw-lock */
	ulint		pass,	/*!< in: pass value; != 0, if the lock
				will be passed to another thread to unlock */
	const char*	file_name, /*!< in: file name where lock requested */
	ulint		line)	/*!< in: line where requested */
{
	ulint	 index;	/* index of the reserved wait cell */
	ulint	 i = 0;	/* spin round count */

	ut_ad(rw_lock_validate(lock));

	rw_s_spin_wait_count++;	/*!< Count calls to this function */
lock_loop:

	/* Spin waiting for the writer field to become free */
	while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {
		if (srv_spin_wait_delay) {
			ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
		}

		i++;
	}

	if (i == SYNC_SPIN_ROUNDS) {
		os_thread_yield();
	}

	if (srv_print_latch_waits) {
		fprintf(stderr,
			"Thread %lu spin wait rw-s-lock at %p"
			" cfile %s cline %lu rnds %lu\n",
			(ulong) os_thread_pf(os_thread_get_curr_id()),
			(void*) lock,
			innobase_basename(lock->cfile_name),
			(ulong) lock->cline, (ulong) i);
	}

	/* We try once again to obtain the lock */
	if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
		rw_s_spin_round_count += i;

		return; /* Success */
	} else {

		if (i < SYNC_SPIN_ROUNDS) {
			goto lock_loop;
		}

		rw_s_spin_round_count += i;

		sync_array_reserve_cell(sync_primary_wait_array,
					lock, RW_LOCK_SHARED,
					file_name, line,
					&index);

		/* Set waiters before checking lock_word to ensure wake-up
                signal is sent. This may lead to some unnecessary signals. */
		rw_lock_set_waiter_flag(lock);

		if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
			sync_array_free_cell(sync_primary_wait_array, index);
			return; /* Success */
		}

		if (srv_print_latch_waits) {
			fprintf(stderr,
				"Thread %lu OS wait rw-s-lock at %p"
				" cfile %s cline %lu\n",
				os_thread_pf(os_thread_get_curr_id()),
				(void*) lock,
				innobase_basename(lock->cfile_name),
				(ulong) lock->cline);
		}

		/* these stats may not be accurate */
		lock->count_os_wait++;
		rw_s_os_wait_count++;

		sync_array_wait_event(sync_primary_wait_array, index);

		i = 0;
		goto lock_loop;
	}
}