コード例 #1
0
ファイル: sync0rw.c プロジェクト: potkungza/MySQL5.1
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;	/* spin round count */

    ut_ad(rw_lock_validate(lock));

lock_loop:
    rw_s_spin_wait_count++;

    /* Spin waiting for the writer field to become free */
    i = 0;

    while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
            && i < SYNC_SPIN_ROUNDS) {
        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,
                lock->cfile_name, (ulong) lock->cline, (ulong) i);
    }

    mutex_enter(rw_lock_get_mutex(lock));

    /* We try once again to obtain the lock */

    if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
        mutex_exit(rw_lock_get_mutex(lock));

        return; /* Success */
    } else {
        /* If we get here, locking did not succeed, we may
        suspend the thread to wait in the wait array */

        rw_s_system_call_count++;

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

        rw_lock_set_waiters(lock, 1);

        mutex_exit(rw_lock_get_mutex(lock));

        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, lock->cfile_name,
                    (ulong) lock->cline);
        }

        rw_s_system_call_count++;
        rw_s_os_wait_count++;

        sync_array_wait_event(sync_primary_wait_array, index);

        goto lock_loop;
    }
}
コード例 #2
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;
	}
}