Exemplo n.º 1
0
void
_init_top(void)
{
	ASSERT(top_init_debug());

	/*
	 * set up the delta layer
	 */
	_init_map();

	/*
	 * Initialise the thread specific data transaction key
	 */
	tsd_create(&topkey, top_threadtrans_destroy);
}
Exemplo n.º 2
0
/*
 * Create threads which set and verify SPLAT_THREAD_TEST_KEYS number of
 * keys.  These threads may then exit by calling thread_exit() which calls
 * tsd_exit() resulting in all their thread specific data being reclaimed.
 * Alternately, the thread may block in which case the thread specific
 * data will be reclaimed as part of tsd_destroy().  In either case all
 * thread specific data must be reclaimed, this is verified by ensuring
 * the registered destructor is called the correct number of times.
 */
static int
splat_thread_test3(struct file *file, void *arg)
{
	int i, rc = 0, expected, wait_count = 0, exit_count = 0;
	thread_priv_t tp;

	tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
	tp.tp_file = file;
        spin_lock_init(&tp.tp_lock);
	init_waitqueue_head(&tp.tp_waitq);
	tp.tp_rc = 0;
	tp.tp_count = 0;
	tp.tp_dtor_count = 0;

	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++) {
		tp.tp_keys[i] = 0;
		tsd_create(&tp.tp_keys[i], splat_thread_dtor3);
	}

	/* Start tsd wait threads */
	for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) {
		if (thread_create(NULL, 0, splat_thread_work3_wait,
				  &tp, 0, &p0, TS_RUN, defclsyspri))
			wait_count++;
	}

	/* All wait threads have setup their tsd and are blocking. */
	wait_event(tp.tp_waitq, splat_thread_count(&tp, wait_count));

	if (tp.tp_dtor_count != 0) {
	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
		    "Prematurely ran %d tsd destructors\n", tp.tp_dtor_count);
		if (!rc)
			rc = -ERANGE;
	}

	/* Start tsd exit threads */
	for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) {
		if (thread_create(NULL, 0, splat_thread_work3_exit,
				  &tp, 0, &p0, TS_RUN, defclsyspri))
			exit_count++;
	}

	/* All exit threads verified tsd and are in the process of exiting */
	wait_event(tp.tp_waitq,splat_thread_count(&tp, wait_count+exit_count));
	msleep(500);

	expected = (SPLAT_THREAD_TEST_KEYS * exit_count);
	if (tp.tp_dtor_count != expected) {
	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
		    "Expected %d exit tsd destructors but saw %d\n",
		    expected, tp.tp_dtor_count);
		if (!rc)
			rc = -ERANGE;
	}

	/* Destroy all keys and associated tsd in blocked threads */
	for (i = 0; i < SPLAT_THREAD_TEST_KEYS; i++)
		tsd_destroy(&tp.tp_keys[i]);

	expected = (SPLAT_THREAD_TEST_KEYS * (exit_count + wait_count));
	if (tp.tp_dtor_count != expected) {
	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
		    "Expected %d wait+exit tsd destructors but saw %d\n",
		    expected, tp.tp_dtor_count);
		if (!rc)
			rc = -ERANGE;
	}

	/* Release the remaining wait threads, sleep briefly while they exit */
	spin_lock(&tp.tp_lock);
	tp.tp_count = 0;
	wake_up_all(&tp.tp_waitq);
	spin_unlock(&tp.tp_lock);
	msleep(500);

	if (tp.tp_rc) {
	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME,
		    "Thread tsd_get()/tsd_set() error %d\n", tp.tp_rc);
		if (!rc)
			rc = tp.tp_rc;
	} else if (!rc) {
	        splat_vprint(file, SPLAT_THREAD_TEST3_NAME, "%s",
		    "Thread specific data verified\n");
	}

	return rc;
}