コード例 #1
0
ファイル: spl-debug.c プロジェクト: chaitanyajoshi27/spl
/* When flag is set do not use a new thread for the debug dump */
int
spl_debug_dumplog(int flags)
{
	struct task_struct *tsk;
	dumplog_priv_t dp;

        init_waitqueue_head(&dp.dp_waitq);
        dp.dp_pid = current->pid;
        dp.dp_flags = flags;
        atomic_set(&dp.dp_done, 0);

        if (dp.dp_flags & DL_NOTHREAD) {
                spl_debug_dumplog_internal(&dp);
        } else {

                tsk = spl_kthread_create(spl_debug_dumplog_thread,(void *)&dp,"spl_debug");
                if (tsk == NULL)
                        return -ENOMEM;

                wake_up_process(tsk);
                wait_event(dp.dp_waitq, atomic_read(&dp.dp_done));
        }

	return 0;
}
コード例 #2
0
ファイル: splat-condvar.c プロジェクト: FireDrunk/spl
static int
splat_condvar_test2(struct file *file, void *arg)
{
	int i, count = 0, rc = 0;
	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
	condvar_priv_t cv;

	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
	cv.cv_file = file;
	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);

	/* Create some threads, the exact number isn't important just as
	 * long as we know how many we managed to create and should expect. */
	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
		ct[i].ct_cvp = &cv;
		ct[i].ct_name = SPLAT_CONDVAR_TEST2_NAME;
		ct[i].ct_rc = 0;
		ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread,
		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);

		if (!IS_ERR(ct[i].ct_thread)) {
			wake_up_process(ct[i].ct_thread);
			count++;
		}
	}

	/* Wait until all threads are waiting on the condition variable */
	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
		schedule();

	/* Wake all threads waiting on the condition variable */
	cv_broadcast(&cv.cv_condvar);

	/* Wait until all threads have exited */
	while ((atomic_read(&cv.cv_condvar.cv_waiters) > 0) || mutex_owner(&cv.cv_mtx))
		schedule();

        splat_vprint(file, SPLAT_CONDVAR_TEST2_NAME, "Correctly woke all "
			   "%d sleeping threads at once\n", count);

	/* Wake everything for the failure case */
	cv_destroy(&cv.cv_condvar);

	/* wait for threads to exit */
	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
		if (!IS_ERR(ct[i].ct_thread))
			kthread_stop(ct[i].ct_thread);
	}
	mutex_destroy(&cv.cv_mtx);

	return rc;
}
コード例 #3
0
ファイル: spl-thread.c プロジェクト: FireDrunk/spl
/* thread_create() may block forever if it cannot create a thread or
 * allocate memory.  This is preferable to returning a NULL which Solaris
 * style callers likely never check for... since it can't fail. */
kthread_t *
__thread_create(caddr_t stk, size_t  stksize, thread_func_t func,
		const char *name, void *args, size_t len, proc_t *pp,
		int state, pri_t pri)
{
	thread_priv_t *tp;
	struct task_struct *tsk;
	char *p;

	/* Option pp is simply ignored */
	/* Variable stack size unsupported */
	ASSERT(stk == NULL);

	tp = kmem_alloc(sizeof(thread_priv_t), KM_PUSHPAGE);
	if (tp == NULL)
		return (NULL);

	tp->tp_magic = TP_MAGIC;
	tp->tp_name_size = strlen(name) + 1;

	tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE);
        if (tp->tp_name == NULL) {
		kmem_free(tp, sizeof(thread_priv_t));
		return (NULL);
	}

	strncpy(tp->tp_name, name, tp->tp_name_size);

	/* Strip trailing "_thread" from passed name which will be the func
	 * name since the exposed API has no parameter for passing a name.
	 */
	p = strstr(tp->tp_name, "_thread");
	if (p)
		p[0] = '\0';

	tp->tp_func  = func;
	tp->tp_args  = args;
	tp->tp_len   = len;
	tp->tp_state = state;
	tp->tp_pri   = pri;

	tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp,
			     "%s", tp->tp_name);
	if (IS_ERR(tsk))
		return (NULL);

	wake_up_process(tsk);
	return ((kthread_t *)tsk);
}
コード例 #4
0
ファイル: splat-condvar.c プロジェクト: FireDrunk/spl
static int
splat_condvar_test1(struct file *file, void *arg)
{
	int i, count = 0, rc = 0;
	condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
	condvar_priv_t cv;

	cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
	cv.cv_file = file;
	mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
	cv_init(&cv.cv_condvar, NULL, CV_DEFAULT, NULL);

	/* Create some threads, the exact number isn't important just as
	 * long as we know how many we managed to create and should expect. */
	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
		ct[i].ct_cvp = &cv;
		ct[i].ct_name = SPLAT_CONDVAR_TEST1_NAME;
		ct[i].ct_rc = 0;
		ct[i].ct_thread = spl_kthread_create(splat_condvar_test12_thread,
		    &ct[i], "%s/%d", SPLAT_CONDVAR_TEST_NAME, i);

		if (!IS_ERR(ct[i].ct_thread)) {
			wake_up_process(ct[i].ct_thread);
			count++;
		}
	}

	/* Wait until all threads are waiting on the condition variable */
	while (atomic_read(&cv.cv_condvar.cv_waiters) != count)
		schedule();

	/* Wake a single thread at a time, wait until it exits */
	for (i = 1; i <= count; i++) {
		cv_signal(&cv.cv_condvar);

		while (atomic_read(&cv.cv_condvar.cv_waiters) > (count - i))
			schedule();

		/* Correct behavior 1 thread woken */
		if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
			continue;

                splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Attempted to "
			   "wake %d thread but work %d threads woke\n",
			   1, count - atomic_read(&cv.cv_condvar.cv_waiters));
		rc = -EINVAL;
		break;
	}

	if (!rc)
                splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Correctly woke "
			   "%d sleeping threads %d at a time\n", count, 1);

	/* Wait until that last nutex is dropped */
	while (mutex_owner(&cv.cv_mtx))
		schedule();

	/* Wake everything for the failure case */
	cv_broadcast(&cv.cv_condvar);
	cv_destroy(&cv.cv_condvar);

	/* wait for threads to exit */
	for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
		if (!IS_ERR(ct[i].ct_thread))
			kthread_stop(ct[i].ct_thread);
	}
	mutex_destroy(&cv.cv_mtx);

	return rc;
}