Beispiel #1
0
int rt_cond_signal(RT_COND *cond)
{
    int err = 0;
    spl_t s;

    xnlock_get_irqsave(&nklock, s);

    cond = xeno_h2obj_validate(cond, XENO_COND_MAGIC, RT_COND);

    if (!cond) {
        err = xeno_handle_error(cond, XENO_COND_MAGIC, RT_COND);
        goto unlock_and_exit;
    }

    if (thread2rtask(xnsynch_wakeup_one_sleeper(&cond->synch_base)) != NULL) {
        xnsynch_set_owner(&cond->synch_base, NULL);	/* No ownership to track. */
        xnpod_schedule();
    }

unlock_and_exit:

    xnlock_put_irqrestore(&nklock, s);

    return err;
}
Beispiel #2
0
static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
{
	struct vfile_priv *priv = xnvfile_iterator_priv(it);
	RT_EVENT *event = xnvfile_priv(it->vfile);
	struct vfile_data *p = data;
	struct xnthread *thread;
	RT_TASK *task;

	priv->value = event->value; /* Refresh as we collect. */

	if (priv->curr == NULL)
		return 0;	/* We are done. */

	/* Fetch current waiter, advance list cursor. */
	thread = link2thread(priv->curr, plink);
	priv->curr = nextpq(xnsynch_wait_queue(&event->synch_base),
			    priv->curr);

	/* Collect thread name to be output in ->show(). */
	strncpy(p->name, xnthread_name(thread), sizeof(p->name));
	task = thread2rtask(thread);
	p->mode = task->wait_args.event.mode;
	p->mask = task->wait_args.event.mask;

	return 1;
}
Beispiel #3
0
int rt_heap_free(RT_HEAP *heap, void *block)
{
	int err, nwake;
	spl_t s;

	if (block == NULL)
		return -EINVAL;

	xnlock_get_irqsave(&nklock, s);

	heap = xeno_h2obj_validate(heap, XENO_HEAP_MAGIC, RT_HEAP);

	if (!heap) {
		err = xeno_handle_error(heap, XENO_HEAP_MAGIC, RT_HEAP);
		goto unlock_and_exit;
	}

	if (heap->mode & H_SINGLE) {	/* No-op in single-block mode. */
		err = 0;
		goto unlock_and_exit;
	}

	err = xnheap_free(&heap->heap_base, block);

	if (!err && xnsynch_nsleepers(&heap->synch_base) > 0) {
		xnpholder_t *holder, *nholder;

		nholder = getheadpq(xnsynch_wait_queue(&heap->synch_base));
		nwake = 0;

		while ((holder = nholder) != NULL) {
			RT_TASK *sleeper =
			    thread2rtask(link2thread(holder, plink));
			void *block;

			block = xnheap_alloc(&heap->heap_base,
					     sleeper->wait_args.heap.size);
			if (block) {
				nholder =
				    xnsynch_wakeup_this_sleeper(&heap->
								synch_base,
								holder);
				sleeper->wait_args.heap.block = block;
				nwake++;
			} else
				nholder =
				    nextpq(xnsynch_wait_queue
					   (&heap->synch_base), holder);
		}

		if (nwake > 0)
			xnpod_schedule();
	}

      unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Beispiel #4
0
static void __task_switch_hook(xnthread_t *thread)
{
	if (xnthread_get_magic(thread) == RTAI_SKIN_MAGIC) {
		RT_TASK *task = thread2rtask(thread);

		if (task->sigfn)
			task->sigfn();
	}
}
Beispiel #5
0
int rt_event_signal(RT_EVENT *event, unsigned long mask)
{
	xnpholder_t *holder, *nholder;
	int err = 0, resched = 0;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	event = xeno_h2obj_validate(event, XENO_EVENT_MAGIC, RT_EVENT);

	if (!event) {
		err = xeno_handle_error(event, XENO_EVENT_MAGIC, RT_EVENT);
		goto unlock_and_exit;
	}

	/* Post the flags. */

	event->value |= mask;

	/* And wakeup any sleeper having its request fulfilled. */

	nholder = getheadpq(xnsynch_wait_queue(&event->synch_base));

	while ((holder = nholder) != NULL) {
		RT_TASK *sleeper = thread2rtask(link2thread(holder, plink));
		int mode = sleeper->wait_args.event.mode;
		unsigned long bits = sleeper->wait_args.event.mask;

		if (((mode & EV_ANY) && (bits & event->value) != 0) ||
		    (!(mode & EV_ANY) && ((bits & event->value) == bits))) {
			sleeper->wait_args.event.mask = (bits & event->value);
			nholder =
			    xnsynch_wakeup_this_sleeper(&event->synch_base,
							holder);
			resched = 1;
		} else
			nholder =
			    nextpq(xnsynch_wait_queue(&event->synch_base),
				   holder);
	}

	if (resched)
		xnpod_schedule();

      unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Beispiel #6
0
static int __heap_read_proc(char *page,
			    char **start,
			    off_t off, int count, int *eof, void *data)
{
	RT_HEAP *heap = (RT_HEAP *)data;
	char *p = page;
	int len;
	spl_t s;

	p += sprintf(p, "type=%s:size=%lu:used=%lu:numaps=%d\n",
		     (heap->mode & H_SHARED) == H_SHARED ? "shared" :
		     (heap->mode & H_MAPPABLE) ? "mappable" : "kernel",
		     xnheap_usable_mem(&heap->heap_base), xnheap_used_mem(&heap->heap_base),
		     atomic_read(&heap->heap_base.archdep.numaps));

	xnlock_get_irqsave(&nklock, s);

	if (xnsynch_nsleepers(&heap->synch_base) > 0) {
		xnpholder_t *holder;

		/* Pended heap -- dump waiters. */

		holder = getheadpq(xnsynch_wait_queue(&heap->synch_base));

		while (holder) {
			xnthread_t *sleeper = link2thread(holder, plink);
			RT_TASK *task = thread2rtask(sleeper);
			size_t size = task->wait_args.heap.size;
			p += sprintf(p, "+%s (size=%zd)\n",
				     xnthread_name(sleeper), size);
			holder =
			    nextpq(xnsynch_wait_queue(&heap->synch_base),
				   holder);
		}
	}

	xnlock_put_irqrestore(&nklock, s);

	len = (p - page) - off;
	if (len <= off + count)
		*eof = 1;
	*start = page + off;
	if (len > count)
		len = count;
	if (len < 0)
		len = 0;

	return len;
}
Beispiel #7
0
static int __event_read_proc(char *page,
			     char **start,
			     off_t off, int count, int *eof, void *data)
{
	RT_EVENT *event = (RT_EVENT *)data;
	char *p = page;
	int len;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	p += sprintf(p, "=0x%lx\n", event->value);

	if (xnsynch_nsleepers(&event->synch_base) > 0) {
		xnpholder_t *holder;

		/* Pended event -- dump waiters. */

		holder = getheadpq(xnsynch_wait_queue(&event->synch_base));

		while (holder) {
			xnthread_t *sleeper = link2thread(holder, plink);
			RT_TASK *task = thread2rtask(sleeper);
			const char *mode =
			    (task->wait_args.event.
			     mode & EV_ANY) ? "any" : "all";
			unsigned long mask = task->wait_args.event.mask;
			p += sprintf(p, "+%s (mask=0x%lx, %s)\n",
				     xnthread_name(sleeper), mask, mode);
			holder =
			    nextpq(xnsynch_wait_queue(&event->synch_base),
				   holder);
		}
	}

	xnlock_put_irqrestore(&nklock, s);

	len = (p - page) - off;
	if (len <= off + count)
		*eof = 1;
	*start = page + off;
	if (len > count)
		len = count;
	if (len < 0)
		len = 0;

	return len;
}
Beispiel #8
0
static void __task_delete_hook(xnthread_t *thread)
{
	RT_TASK *task;

	if (xnthread_get_magic(thread) != RTAI_SKIN_MAGIC)
		return;

	task = thread2rtask(thread);

	removeq(&__rtai_task_q, &task->link);

	rtai_mark_deleted(task);

	if (xnthread_test_state(&task->thread_base, XNSHADOW))
		xnheap_schedule_free(&kheap, task, &task->link);
}