コード例 #1
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
static void
interval_tree_intersection_1(interval_tree tree, uint64_t start, uint64_t end,
							 varray * dest)
{
	interval_tree_node node;

	node = splay_tree_lookup(tree->splay, start);
	if (!node)
	{
		node = splay_tree_predecessor(tree->splay, start);
		if (!node || INTERVAL_END(node) <= start)
			node = splay_tree_successor(tree->splay, start);
	}
	if (!node)
		node = splay_tree_successor(tree->splay, start);

	for (; node && INTERVAL_START(node) < end;
		 node = splay_tree_successor(tree->splay, INTERVAL_START(node)))
	{
		interval *x;

		VARRAY_EMPTY_PUSH(*dest);
		x = &VARRAY_TOP(*dest, interval);
		x->start = MAX(start, INTERVAL_START(node));
		x->end = MIN(end, INTERVAL_END(node));
	}
}
コード例 #2
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
static int interval_tree_add_1(splay_tree_node node, void *data)
{
	interval_tree tree = (interval_tree) data;

	interval_tree_insert(tree, INTERVAL_START(node), INTERVAL_END(node));
	return 0;
}
コード例 #3
0
static int
mp3_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
    //static char tmp[E7B_MP3_MAX_INPUTSIZE];
    static char tmp[3*1024];
    int n = sizeof tmp;
    int ret;

    INTERVAL_START(timeWrite);

    if (n > count)
	n = count;

    // We should really redefine the lower level interface so that we
    // can avoid this copy.  Rather than tmp we should go straight to
    // the epics.  This is safe though for now.
    if (copy_from_user(tmp, buf, n))
	ret = -EFAULT;
    else
    {

	TRACE(4, ">>MP3_WRITE n=%u\n", n);
	ret = mp3decInputData(tmp, n);
	TRACE(4, "<<MP3_WRITE ret=%u\n", ret);
    }

    INTERVAL_STOP(timeWrite);
    return ret;
}
コード例 #4
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
static void
interval_tree_complement_1(interval_tree tree, uint64_t start, uint64_t end,
						   varray * dest)
{
	interval_tree_node node;
	uint64_t last;

	node = splay_tree_lookup(tree->splay, start);
	if (node)
	{
		last = INTERVAL_END(node);
	}
	else
	{
		node = splay_tree_predecessor(tree->splay, start);
		if (node && INTERVAL_END(node) > start)
			last = INTERVAL_END(node);
		else
			last = start;
	}
	node = splay_tree_successor(tree->splay, start);

	while (last < end)
	{
		interval *x;

		VARRAY_EMPTY_PUSH(*dest);
		x = &VARRAY_TOP(*dest, interval);
		x->start = last;

		if (node)
		{
			x->end = INTERVAL_START(node);
			last = INTERVAL_END(node);
			node = splay_tree_successor(tree->splay, INTERVAL_START(node));
		}
		else
		{
			x->end = end;
			break;
		}
	}
}
コード例 #5
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
static int interval_tree_sub_1(splay_tree_node node, void *data)
{
	interval_tree tree = (interval_tree) data;

	interval_tree_delete(tree, INTERVAL_START(node), INTERVAL_END(node));

	/* Stop traversing when TREE is empty and thus no more intervals can be
	   deleted.  */
	return tree->splay->root == NULL;
}
コード例 #6
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
/*! Print the interval in NODE to file DATA.  */
static int print_interval_tree_node(splay_tree_node node, void *data)
{
	FILE *f = (FILE *) data;

	fprintf(f, "[");
	fprintf(f, "%" PRIu64, INTERVAL_START(node));
	fprintf(f, ",");
	fprintf(f, "%" PRIu64, INTERVAL_END(node));
	fprintf(f, ")\n");
	return 0;
}
コード例 #7
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
static bool
interval_tree_write_1(interval_tree_node node, int fd,
					  interval_tree_write_data * data)
{
	bool r;

	/* Process left subtree.  */
	if (node->left)
	{
		r = interval_tree_write_1(node->left, fd, data);
		if (!r)
			return r;
	}

	/* Process current node.  */
	data->intervals[data->n].start = u64_to_le(INTERVAL_START(node));
	data->intervals[data->n].end = u64_to_le(INTERVAL_END(node));
	data->n++;
	if (data->n == INTERVAL_COUNT)
	{
		r = full_write(fd, data->intervals, INTERVAL_COUNT * sizeof(interval));
		if (!r)
			return r;
		data->n = 0;
	}

	/* Process right subtree.  */
	if (node->right)
	{
		r = interval_tree_write_1(node->right, fd, data);
		if (!r)
			return r;
	}

	return true;
}
コード例 #8
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
interval_tree_node
interval_tree_insert(interval_tree tree, uint64_t start, uint64_t end)
{
	splay_tree_node node, prev, next;

	CHECK_MUTEX_LOCKED(tree->mutex);

	if ((node = splay_tree_lookup(tree->splay, start)) != NULL)
	{
		/* The START of interval is already in the tree.  */

		if (INTERVAL_END(node) >= end)
		{
			/* There already is a larger interval starting in START so we have 
			   nothing to do.  */
			return node;
		}
		INTERVAL_END(node) = end;
	}
	else
	{
		/* Lookup the predecessor and successor of key START.  */
		prev = splay_tree_predecessor(tree->splay, start);
		next = splay_tree_successor(tree->splay, start);

		if (prev && INTERVAL_END(prev) >= start)
		{
			/* We are extending PREV.  */
			node = prev;
			if (INTERVAL_END(node) < end)
				INTERVAL_END(node) = end;
		}
		else if (next && INTERVAL_START(next) <= end)
		{
			/* We are extending NEXT.  */
			node = next;
			if (INTERVAL_START(node) > start)
				INTERVAL_START(node) = start;
			if (INTERVAL_END(node) < end)
				INTERVAL_END(node) = end;
		}
		else
		{
			/* We are really inserting a new node.  */
			node = splay_tree_insert(tree->splay, start, end);
			tree->size++;
		}
	}

	/* Merge the successors if they are covered by [START, END).  */
	while ((next = splay_tree_successor(tree->splay,
										INTERVAL_START(node))) != NULL)
	{
		if (INTERVAL_START(next) <= INTERVAL_END(node))
		{
			if (INTERVAL_END(node) < INTERVAL_END(next))
				INTERVAL_END(node) = INTERVAL_END(next);
			splay_tree_delete(tree->splay, INTERVAL_START(next));
			tree->size--;
		}
		else
			break;
	}

	return node;
}
コード例 #9
0
ファイル: interval.c プロジェクト: snua12/zlomekfs
void interval_tree_delete(interval_tree tree, uint64_t start, uint64_t end)
{
	splay_tree_node node, prev, next;

	CHECK_MUTEX_LOCKED(tree->mutex);

	if ((node = splay_tree_lookup(tree->splay, start)) != NULL)
	{
		tree->deleted = true;
		if (INTERVAL_END(node) > end)
		{
			/* We are shortening the interval NODE.  */
			INTERVAL_START(node) = end;
			return;
		}
		else
		{
			splay_tree_delete(tree->splay, start);
			tree->size--;
		}
	}
	else
	{
		prev = splay_tree_predecessor(tree->splay, start);

		if (prev && start < INTERVAL_END(prev))
		{
			tree->deleted = true;
			if (INTERVAL_END(prev) > end)
			{
				/* We are cutting a subinterval from interval PREV.  */
				splay_tree_insert(tree->splay, end, INTERVAL_END(prev));
				tree->size++;
				INTERVAL_END(prev) = start;
				return;
			}
			else
			{
				/* We are shortening the interval PREV.  */
				INTERVAL_END(prev) = start;
			}
		}
	}

	/* Delete rest intervals which intersect [START, END).  */
	while (1)
	{
		next = splay_tree_successor(tree->splay, start);
		if (!next || INTERVAL_START(next) >= end)
			break;

		tree->deleted = true;
		if (INTERVAL_END(next) <= end)
		{
			splay_tree_delete(tree->splay, INTERVAL_START(next));
			tree->size--;
		}
		else
		{
			INTERVAL_START(next) = end;
			return;
		}
	}
}
コード例 #10
0
static int
mp3_ioctl(struct inode *inode, struct file *fp, unsigned int command, unsigned long arg)
{
    int retval = 0;

    TRACE(1, "%s\n", __FUNCTION__);

    switch (command)
    {
    case E7B_MP3_INIT:
	{
	    int ret;
	    TRACE(1, ">>E7B_MP3_INIT\n");

	    // Start of Stream

	    /* fill references */
	    INTERVAL_START(timeInit);
	    ret = mp3decInit();
	    INTERVAL_STOP(timeInit);

	    if (ret < 0)
		return -EIO;
	}

	break;
    case E7B_MP3_DECODE:
	{
	    int ret;
	    e7b_mp3_decode dp;
	    TRACE(1, ">>E7B_MP3_DECODE\n");

	    switch (mp3_driver_state)
	    {
	    case mp3_driver_idle:
		ret = mp3decDecode();
		mp3_driver_state = mp3_driver_decoding;
		break;
	    case mp3_driver_decoding:
		ret = mp3decContinue();
		break;
	    default:
		return -EIO;
	    }

	    dp.samplesReady = 0;
	    dp.needInput = 0;
	    dp.decReturn = 0;

	    if (ret == 0)
	    {
		mp3decDecodeFinish(&mp3_buff->out[0].hdr, &dp.samplesReady, mp3_buff->out[0].data, &dp.decReturn);

		if (dp.decReturn != 0)
		    pnx0106_epics_printk("Decode returned 0x%x\n", dp.decReturn);

		mp3_driver_state = mp3_driver_idle;
	    }
	    else
		dp.needInput = 1;

	    TRACE(3, "<<E7B_MP3_DECODE sReady=%u ret=%d\n", dp.samplesReady, ret);

	    if (copy_to_user((void *)arg, &dp, sizeof(dp)))
		return -EFAULT;
	}

	break;
    case E7B_MP3_RESET:
	TRACE(1, ">>E7B_MP3_RESET\n");
	INTERVAL_START(timeReset);
	wait_epics_idle();
	mp3decReset();
	INTERVAL_STOP(timeReset);
	break;
    case E7B_MP3_INPUT_EOF:
	mp3decInputEOF();
	break;
    case E7B_MP3_STREAM:

	{
	    int ret;
	    u32 decReturn;

        TRACE(4, ">>E7B_MP3_STREAM\n");

	    switch (mp3_driver_state)
	    {
	    case mp3_driver_idle:
		ret = mp3decStreamStart();

		mp3_driver_state = mp3_driver_streaming;
		break;
	    case mp3_driver_streaming:
		ret = mp3decContinue();
		break;
	    default:
		return -EIO;
	    }

	    decReturn = 0;

	    if (ret == 0)
	    {
		mp3decStreamFinish(&decReturn);

		if (decReturn != 0)
		    printk("Stream finish returned 0x%x\n", decReturn);

		mp3_driver_state = mp3_driver_idle;
	    }

	    if (copy_to_user((void *)arg, &decReturn, sizeof decReturn))
		return -EFAULT;
	}

	break;

    case E7B_MP3_STREAM_RESUME:
    {
	    int ret;

        TRACE(4, ">>E7B_MP3_STREAM_RESUME\n");

	    switch (mp3_driver_state)
	    {
	    case mp3_driver_idle:
		case mp3_driver_streaming:
		ret = mp3decStreamResume();
        mp3_driver_state = mp3_driver_streaming;
        break;
	    default:
		return -EIO;
	    }
	}
    break;


    case E7B_MP3_STREAM_GETPCM:
	{
	    e7b_mp3_decode sgp;

	    INTERVAL_START(timeGetPCM);
	    TRACE(4, ">>E7B_MP3_STREAM_GETPCM \n");

	    sgp.needInput = 0;
	    sgp.decReturn = 0;

	    mp3decStreamGetPCM(
		   &mp3_buff->out[0].hdr,
		   &sgp.samplesReady,
		   mp3_buff->out[0].data,
		   &sgp.decReturn); 		// ~ redundant with cSamplesRequested
	    TRACE(4, "<<E7B_MP3_STREAM_GETPCM sRet=%u decReturn=%d\n", sgp.samplesReady, sgp.decReturn);

	    if (copy_to_user((void *)arg, &sgp, sizeof(sgp)))
		retval = -EFAULT;

	    INTERVAL_STOP(timeGetPCM);
	}

	break;
    }


    return retval;
}