Exemplo n.º 1
0
int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
{
	int sched = 0;

	LOCK(queue);
	int status = LOAD_S32(queue->s.status);
	if (odp_unlikely(status < QUEUE_STATUS_READY)) {
		UNLOCK(queue);
		ODP_ERR("Bad queue status\n");
		return -1;
	}

	if (LOAD_PTR(queue->s.head) == NULL) {
		/* Empty queue */
		STORE_PTR(queue->s.head, buf_hdr);
		STORE_PTR(queue->s.tail, buf_hdr);
		buf_hdr->next = NULL;
	} else {
		STORE_PTR(((typeof(queue->s.tail))LOAD_PTR(queue->s.tail))->next, buf_hdr);
		STORE_PTR(queue->s.tail, buf_hdr);
		buf_hdr->next = NULL;
	}

	if (status == QUEUE_STATUS_NOTSCHED) {
		STORE_S32(queue->s.status, QUEUE_STATUS_SCHED);
		sched = 1; /* retval: schedule queue */
	}
	UNLOCK(queue);

	/* Add queue to scheduling */
	if (sched)
		schedule_queue(queue);

	return 0;
}
Exemplo n.º 2
0
odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
{
	odp_buffer_hdr_t *buf_hdr;

	if (LOAD_PTR(queue->s.head) == NULL)
		return NULL;

	LOCK(queue);

	buf_hdr       = LOAD_PTR(queue->s.head);
	if (buf_hdr == NULL) {
		UNLOCK(queue);
		return NULL;
	}

	INVALIDATE(buf_hdr);
	STORE_PTR(queue->s.head, buf_hdr->next);
	if (buf_hdr->next == NULL) {
		/* Queue is now empty */
		STORE_PTR(queue->s.tail, NULL);
		if (LOAD_S32(queue->s.status) == QUEUE_STATUS_SCHED)
			STORE_S32(queue->s.status, QUEUE_STATUS_NOTSCHED);
	}

	buf_hdr->next = NULL;


	UNLOCK(queue);

	return buf_hdr;
}
Exemplo n.º 3
0
int odp_queue_term_global(void)
{
	int ret = 0;
	int rc = 0;
	queue_entry_t *queue;
	int i;

	for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
		queue = &queue_tbl->queue[i];
		LOCK(queue);
		if (LOAD_S32(queue->s.status) != QUEUE_STATUS_FREE) {

			ODP_ERR("Not destroyed queue: %s\n", queue->s.name);
			rc = -1;
		}
		UNLOCK(queue);
	}

	ret = odp_shm_free(odp_shm_lookup("odp_queues"));
	if (ret < 0) {
		ODP_ERR("shm free failed for odp_queues");
		rc = -1;
	}

	return rc;
}
Exemplo n.º 4
0
void queue_destroy_finalize(queue_entry_t *queue)
{
	LOCK(queue);

	if (LOAD_S32(queue->s.status) == QUEUE_STATUS_DESTROYED) {
		INVALIDATE(queue);
		queue->s.status = QUEUE_STATUS_FREE;
		schedule_queue_destroy(queue);
	}
	UNLOCK(queue);
}
Exemplo n.º 5
0
/* Only one writer can recurse the lock */
void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *rlock)
{
	int thr = odp_thread_id();

	if (LOAD_S32(rlock->wr_owner) == thr) {
		rlock->wr_cnt++;
		return;
	}

	odp_rwlock_write_lock(&rlock->lock);
	STORE_U32(rlock->wr_owner, thr);
	rlock->wr_cnt   = 1;
}
Exemplo n.º 6
0
int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
{
	odp_buffer_hdr_t *hdr;
	int i;

	LOCK(queue);
	int status = LOAD_S32(queue->s.status);
	if (odp_unlikely(status < QUEUE_STATUS_READY)) {
		/* Bad queue, or queue has been destroyed.
		 * Scheduler finalizes queue destroy after this. */
		UNLOCK(queue);
		return -1;
	}

	hdr = LOAD_PTR(queue->s.head);

	if (hdr == NULL) {
		/* Already empty queue */
		if (status == QUEUE_STATUS_SCHED)
			STORE_S32(queue->s.status, QUEUE_STATUS_NOTSCHED);

		UNLOCK(queue);
		return 0;
	}

	for (i = 0; i < num && hdr; i++) {
		INVALIDATE(hdr);
		buf_hdr[i]       = hdr;
		hdr              = hdr->next;
		buf_hdr[i]->next = NULL;
	}

	STORE_PTR(queue->s.head, hdr);

	if (hdr == NULL) {
		/* Queue is now empty */
		STORE_PTR(queue->s.tail, NULL);
	}

	UNLOCK(queue);

	return i;
}
Exemplo n.º 7
0
odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
			     odp_queue_param_t *param)
{
	uint32_t i;
	queue_entry_t *queue;
	odp_queue_t handle = ODP_QUEUE_INVALID;

	for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
		queue = &queue_tbl->queue[i];

		if (LOAD_S32(queue->s.status) != QUEUE_STATUS_FREE)
			continue;

		LOCK(queue);
		INVALIDATE(queue);
		if (queue->s.status == QUEUE_STATUS_FREE) {
			queue_init(queue, name, type, param);

			if (type == ODP_QUEUE_TYPE_SCHED ||
			    type == ODP_QUEUE_TYPE_PKTIN)
				queue->s.status = QUEUE_STATUS_NOTSCHED;
			else
				queue->s.status = QUEUE_STATUS_READY;

			handle = queue->s.handle;
			UNLOCK(queue);
			break;
		}
		UNLOCK(queue);
	}

	if (handle != ODP_QUEUE_INVALID &&
	    (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) {
		if (schedule_queue_init(queue)) {
			ODP_ERR("schedule queue init failed\n");
			return ODP_QUEUE_INVALID;
		}
	}

	return handle;
}
Exemplo n.º 8
0
int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
{
	int sched = 0;
	int i;
	odp_buffer_hdr_t *tail;

	for (i = 0; i < num - 1; i++)
		buf_hdr[i]->next = buf_hdr[i+1];

	tail = buf_hdr[num-1];
	buf_hdr[num-1]->next = NULL;

	LOCK(queue);
	int status = LOAD_S32(queue->s.status);
	if (odp_unlikely(status < QUEUE_STATUS_READY)) {
		UNLOCK(queue);
		ODP_ERR("Bad queue status\n");
		return -1;
	}

	/* Empty queue */
	if (LOAD_PTR(queue->s.head) == NULL)
		STORE_PTR(queue->s.head, buf_hdr[0]);
	else
		STORE_PTR(((typeof(queue->s.tail))LOAD_PTR(queue->s.tail))->next, buf_hdr[0]);

	STORE_PTR(queue->s.tail, tail);

	if (status == QUEUE_STATUS_NOTSCHED) {
		STORE_PTR(queue->s.status, QUEUE_STATUS_SCHED);
		sched = 1; /* retval: schedule queue */
	}
	UNLOCK(queue);

	/* Add queue to scheduling */
	if (sched)
		schedule_queue(queue);

	return num; /* All events enqueued */
}