⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sync0arr.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
			rwlock->last_x_file_name,			(ulong) rwlock->last_x_line);	} else {		ut_error;	}        if (!cell->waiting) {		fputs("wait has ended\n", file);	}        if (cell->event_set) {		fputs("wait is ending\n", file);	}}#ifdef UNIV_SYNC_DEBUG/**********************************************************************Looks for a cell with the given thread id. */staticsync_cell_t*sync_array_find_thread(/*===================*/				/* out: pointer to cell or NULL				if not found */        sync_array_t*	arr,	/* in: wait array */	os_thread_id_t	thread)	/* in: thread id */{        ulint           i;        sync_cell_t*   	cell;        for (i = 0; i < arr->n_cells; i++) {		cell = sync_array_get_nth_cell(arr, i);        	                if (cell->wait_object != NULL		    && os_thread_eq(cell->thread, thread)) {		    	return(cell);	/* Found */                }        }	return(NULL);	/* Not found */}/**********************************************************************Recursion step for deadlock detection. */staticiboolsync_array_deadlock_step(/*=====================*/				/* out: TRUE if deadlock detected */        sync_array_t*	arr,	/* in: wait array; NOTE! the caller must        			own the mutex to array */	sync_cell_t*	start,	/* in: cell where recursive search				started */	os_thread_id_t	thread,	/* in: thread to look at */	ulint		pass,	/* in: pass value */	ulint		depth)	/* in: recursion depth */{	sync_cell_t*	new;	ibool		ret;	depth++;	if (pass != 0) {		/* If pass != 0, then we do not know which threads are		responsible of releasing the lock, and no deadlock can		be detected. */		return(FALSE);	}			    		new = sync_array_find_thread(arr, thread);	if (new == start) {		/* Stop running of other threads */		ut_dbg_stop_threads = TRUE;		/* Deadlock */		fputs("########################################\n"			"DEADLOCK of threads detected!\n", stderr);		return(TRUE);	} else if (new) {		ret = sync_array_detect_deadlock(arr, start, new, depth);		if (ret) {			return(TRUE);		}	}	return(FALSE);}/**********************************************************************This function is called only in the debug version. Detects a deadlockof one or more threads because of waits of semaphores. */staticiboolsync_array_detect_deadlock(/*=======================*/				/* out: TRUE if deadlock detected */        sync_array_t*	arr,	/* in: wait array; NOTE! the caller must        			own the mutex to array */	sync_cell_t*	start,	/* in: cell where recursive search started */	sync_cell_t*	cell,	/* in: cell to search */	ulint		depth)	/* in: recursion depth */{	mutex_t*	mutex;	rw_lock_t*	lock;	os_thread_id_t	thread;	ibool		ret;	rw_lock_debug_t*debug;	        ut_a(arr && start && cell);	ut_ad(cell->wait_object);	ut_ad(os_thread_get_curr_id() == start->thread);	ut_ad(depth < 100);		depth++;		if (cell->event_set || !cell->waiting) {		return(FALSE); /* No deadlock here */	}		if (cell->request_type == SYNC_MUTEX) {		mutex = cell->wait_object;		if (mutex_get_lock_word(mutex) != 0) {			thread = mutex->thread_id;			/* Note that mutex->thread_id above may be			also OS_THREAD_ID_UNDEFINED, because the			thread which held the mutex maybe has not			yet updated the value, or it has already			released the mutex: in this case no deadlock			can occur, as the wait array cannot contain			a thread with ID_UNDEFINED value. */			ret = sync_array_deadlock_step(arr, start, thread, 0,								depth);			if (ret) {				fprintf(stderr,			"Mutex %p owned by thread %lu file %s line %lu\n",					mutex, (ulong) os_thread_pf(mutex->thread_id),					mutex->file_name, (ulong) mutex->line);				sync_array_cell_print(stderr, cell);				return(TRUE);			}		}		return(FALSE); /* No deadlock */	} else if (cell->request_type == RW_LOCK_EX) {	    lock = cell->wait_object;	    debug = UT_LIST_GET_FIRST(lock->debug_list);	    while (debug != NULL) {		thread = debug->thread_id;		if (((debug->lock_type == RW_LOCK_EX)	             && !os_thread_eq(thread, cell->thread))	            || ((debug->lock_type == RW_LOCK_WAIT_EX)			&& !os_thread_eq(thread, cell->thread))	            || (debug->lock_type == RW_LOCK_SHARED)) {			/* The (wait) x-lock request can block infinitely			only if someone (can be also cell thread) is holding			s-lock, or someone (cannot be cell thread) (wait)			x-lock, and he is blocked by start thread */			ret = sync_array_deadlock_step(arr, start, thread,							debug->pass,							depth);			if (ret) {			print:				fprintf(stderr, "rw-lock %p ", lock);				sync_array_cell_print(stderr, cell);				rw_lock_debug_print(debug);				return(TRUE);			}		}		debug = UT_LIST_GET_NEXT(list, debug);	    }	    return(FALSE);	} else if (cell->request_type == RW_LOCK_SHARED) {	    lock = cell->wait_object;	    debug = UT_LIST_GET_FIRST(lock->debug_list);	    while (debug != NULL) {		thread = debug->thread_id;		if ((debug->lock_type == RW_LOCK_EX)	            || (debug->lock_type == RW_LOCK_WAIT_EX)) {			/* The s-lock request can block infinitely only if			someone (can also be cell thread) is holding (wait)			x-lock, and he is blocked by start thread */			ret = sync_array_deadlock_step(arr, start, thread,							debug->pass,							depth);			if (ret) {				goto print;			}		}		debug = UT_LIST_GET_NEXT(list, debug);	    }	    return(FALSE);	} else {		ut_error;	}	return(TRUE); 	/* Execution never reaches this line: for compiler			fooling only */}#endif /* UNIV_SYNC_DEBUG *//**********************************************************************Determines if we can wake up the thread waiting for a sempahore. */staticiboolsync_arr_cell_can_wake_up(/*======================*/	sync_cell_t*	cell)	/* in: cell to search */{	mutex_t*	mutex;	rw_lock_t*	lock;		if (cell->request_type == SYNC_MUTEX) {		mutex = cell->wait_object;		if (mutex_get_lock_word(mutex) == 0) {			return(TRUE);		}	} else if (cell->request_type == RW_LOCK_EX) {	    	lock = cell->wait_object;	    	if (rw_lock_get_reader_count(lock) == 0		    && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {			return(TRUE);		}	    	if (rw_lock_get_reader_count(lock) == 0		    && rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX		    && os_thread_eq(lock->writer_thread, cell->thread)) {			return(TRUE);		}	} else if (cell->request_type == RW_LOCK_SHARED) {	    	lock = cell->wait_object;		if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {					return(TRUE);		}	}	return(FALSE);}/**********************************************************************Frees the cell. NOTE! sync_array_wait_event frees the cellautomatically! */voidsync_array_free_cell(/*=================*/	sync_array_t*	arr,	/* in: wait array */        ulint    	index)  /* in: index of the cell in array */{        sync_cell_t*   	cell;                sync_array_enter(arr);        cell = sync_array_get_nth_cell(arr, index);        ut_a(cell->wait_object != NULL);	cell->wait_object =  NULL;	ut_a(arr->n_reserved > 0);	arr->n_reserved--;        sync_array_exit(arr);}/**************************************************************************Looks for the cells in the wait array which refer to the wait objectspecified, and sets their corresponding events to the signaled state. In thisway releases the threads waiting for the object to contend for the object.It is possible that no such cell is found, in which case does nothing. */voidsync_array_signal_object(/*=====================*/	sync_array_t*	arr,	/* in: wait array */	void*		object)	/* in: wait object */{        sync_cell_t*   	cell;        ulint           count;        ulint           i;        sync_array_enter(arr);	arr->sg_count++;	i = 0;	count = 0;        while (count < arr->n_reserved) {        	cell = sync_array_get_nth_cell(arr, i);                if (cell->wait_object != NULL) {                        count++;                        if (cell->wait_object == object) {                        	sync_cell_event_set(cell);                        }                }                i++;        }        sync_array_exit(arr);}/**************************************************************************If the wakeup algorithm does not work perfectly at semaphore relases,this function will do the waking (see the comment in mutex_exit). Thisfunction should be called about every 1 second in the server. */voidsync_arr_wake_threads_if_sema_free(void)/*====================================*/{	sync_array_t*	arr 	= sync_primary_wait_array;        sync_cell_t*   	cell;        ulint           count;        ulint           i;        sync_array_enter(arr);	i = 0;	count = 0;        while (count < arr->n_reserved) {        	cell = sync_array_get_nth_cell(arr, i);                if (cell->wait_object != NULL) {                        count++;                        if (sync_arr_cell_can_wake_up(cell)) {                        	sync_cell_event_set(cell);                        }                }                i++;        }        sync_array_exit(arr);}/**************************************************************************Prints warnings of long semaphore waits to stderr. */iboolsync_array_print_long_waits(void)/*=============================*/			/* out: TRUE if fatal semaphore wait threshold			was exceeded */{        sync_cell_t*   	cell;        ibool		old_val;	ibool		noticed = FALSE;	ulint           i;	ulint		fatal_timeout = srv_fatal_semaphore_wait_threshold;	ibool		fatal = FALSE;        for (i = 0; i < sync_primary_wait_array->n_cells; i++) {        	cell = sync_array_get_nth_cell(sync_primary_wait_array, i);                if (cell->wait_object != NULL		    && difftime(time(NULL), cell->reservation_time) > 240) {			fputs("InnoDB: Warning: a long semaphore wait:\n",				stderr);			sync_array_cell_print(stderr, cell);			noticed = TRUE;                }                if (cell->wait_object != NULL		    && difftime(time(NULL), cell->reservation_time)		    > fatal_timeout) {			fatal = TRUE;                }       	}	if (noticed) {		fprintf(stderr,"InnoDB: ###### Starts InnoDB Monitor for 30 secs to print diagnostic info:\n");        	old_val = srv_print_innodb_monitor;		/* If some crucial semaphore is reserved, then also the InnoDB		Monitor can hang, and we do not get diagnostics. Since in		many cases an InnoDB hang is caused by a pwrite() or a pread()		call hanging inside the operating system, let us print right		now the values of pending calls of these. */		fprintf(stderr,"InnoDB: Pending preads %lu, pwrites %lu\n", (ulong)os_file_n_pending_preads,				(ulong)os_file_n_pending_pwrites);        	srv_print_innodb_monitor = TRUE;		os_event_set(srv_lock_timeout_thread_event);        	os_thread_sleep(30000000);        	srv_print_innodb_monitor = old_val;		fprintf(stderr,"InnoDB: ###### Diagnostic info printed to the standard error stream\n");	}	return(fatal);}/**************************************************************************Prints info of the wait array. */staticvoidsync_array_output_info(/*===================*/	FILE*		file,	/* in: file where to print */	sync_array_t*	arr)	/* in: wait array; NOTE! caller must own the				mutex */{        sync_cell_t*   	cell;        ulint           count;	ulint           i;	fprintf(file,		"OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",						(long) arr->res_count, (long) arr->sg_count);	i = 0;	count = 0;        while (count < arr->n_reserved) {        	cell = sync_array_get_nth_cell(arr, i);                if (cell->wait_object != NULL) {                        count++;			sync_array_cell_print(file, cell);                }                i++;       	}}/**************************************************************************Prints info of the wait array. */voidsync_array_print_info(/*==================*/	FILE*		file,	/* in: file where to print */	sync_array_t*	arr)	/* in: wait array */{        sync_array_enter(arr);	sync_array_output_info(file, arr);                sync_array_exit(arr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -