event.c revision aa97dd1c
1/*
2 * Copyright (c) 2016  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <rte_errno.h>
17#include <rte_malloc.h>
18#include <rte_log.h>
19#include <tle_event.h>
20
21#include "osdep.h"
22
23struct tle_evq *
24tle_evq_create(const struct tle_evq_param *prm)
25{
26	struct tle_evq *evq;
27	size_t sz;
28	uint32_t i;
29
30	if (prm == NULL) {
31		rte_errno = EINVAL;
32		return NULL;
33	}
34
35	sz = sizeof(*evq) + sizeof(evq->events[0]) * prm->max_events;
36	evq =  rte_zmalloc_socket(NULL, sz, RTE_CACHE_LINE_SIZE,
37		prm->socket_id);
38	if (evq == NULL) {
39		UDP_LOG(ERR, "allocation of %zu bytes for "
40			"new tle_evq(%u) on socket %d failed\n",
41			sz, prm->max_events, prm->socket_id);
42		return NULL;
43	}
44
45	TAILQ_INIT(&evq->armed);
46	TAILQ_INIT(&evq->free);
47
48	for (i = 0; i != prm->max_events; i++) {
49		evq->events[i].head = evq;
50		TAILQ_INSERT_TAIL(&evq->free, evq->events + i, ql);
51	}
52
53	evq->nb_events = i;
54	evq->nb_free = i;
55
56	return evq;
57}
58
59void
60tle_evq_destroy(struct tle_evq *evq)
61{
62	rte_free(evq);
63}
64
65struct tle_event *
66tle_event_alloc(struct tle_evq *evq, const void *data)
67{
68	struct tle_event *h;
69
70	if (evq == NULL) {
71		rte_errno = EINVAL;
72		return NULL;
73	}
74
75	rte_spinlock_lock(&evq->lock);
76	h = TAILQ_FIRST(&evq->free);
77	if (h != NULL) {
78		TAILQ_REMOVE(&evq->free, h, ql);
79		evq->nb_free--;
80		h->data = data;
81	} else
82		rte_errno = ENOMEM;
83	rte_spinlock_unlock(&evq->lock);
84	return h;
85}
86
87void
88tle_event_free(struct tle_event *ev)
89{
90	struct tle_evq *q;
91
92	if (ev == NULL) {
93		rte_errno = EINVAL;
94		return;
95	}
96
97	q = ev->head;
98	rte_spinlock_lock(&q->lock);
99	ev->data = NULL;
100	ev->state = TLE_SEV_IDLE;
101	TAILQ_INSERT_HEAD(&q->free, ev, ql);
102	q->nb_free++;
103	rte_spinlock_unlock(&q->lock);
104}
105