New upstream version 18.02
[deb_dpdk.git] / examples / performance-thread / common / lthread_objcache.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015 Intel Corporation
3  */
4 #ifndef LTHREAD_OBJCACHE_H_
5 #define LTHREAD_OBJCACHE_H_
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 #include <string.h>
12
13 #include <rte_per_lcore.h>
14 #include <rte_malloc.h>
15 #include <rte_memory.h>
16
17 #include "lthread_int.h"
18 #include "lthread_diag.h"
19 #include "lthread_queue.h"
20
21
22 RTE_DECLARE_PER_LCORE(struct lthread_sched *, this_sched);
23
24 struct lthread_objcache {
25         struct lthread_queue *q;
26         size_t obj_size;
27         int prealloc_size;
28         char name[LT_MAX_NAME_SIZE];
29
30         DIAG_COUNT_DEFINE(rd);
31         DIAG_COUNT_DEFINE(wr);
32         DIAG_COUNT_DEFINE(prealloc);
33         DIAG_COUNT_DEFINE(capacity);
34         DIAG_COUNT_DEFINE(available);
35 };
36
37 /*
38  * Create a cache
39  */
40 static inline struct
41 lthread_objcache *_lthread_objcache_create(const char *name,
42                                         size_t obj_size,
43                                         int prealloc_size)
44 {
45         struct lthread_objcache *c =
46             rte_malloc_socket(NULL, sizeof(struct lthread_objcache),
47                                 RTE_CACHE_LINE_SIZE,
48                                 rte_socket_id());
49         if (c == NULL)
50                 return NULL;
51
52         c->q = _lthread_queue_create("cache queue");
53         if (c->q == NULL) {
54                 rte_free(c);
55                 return NULL;
56         }
57         c->obj_size = obj_size;
58         c->prealloc_size = prealloc_size;
59
60         if (name != NULL)
61                 strncpy(c->name, name, LT_MAX_NAME_SIZE);
62         c->name[sizeof(c->name)-1] = 0;
63
64         DIAG_COUNT_INIT(c, rd);
65         DIAG_COUNT_INIT(c, wr);
66         DIAG_COUNT_INIT(c, prealloc);
67         DIAG_COUNT_INIT(c, capacity);
68         DIAG_COUNT_INIT(c, available);
69         return c;
70 }
71
72 /*
73  * Destroy an objcache
74  */
75 static inline int
76 _lthread_objcache_destroy(struct lthread_objcache *c)
77 {
78         if (_lthread_queue_destroy(c->q) == 0) {
79                 rte_free(c);
80                 return 0;
81         }
82         return -1;
83 }
84
85 /*
86  * Allocate an object from an object cache
87  */
88 static inline void *
89 _lthread_objcache_alloc(struct lthread_objcache *c)
90 {
91         int i;
92         void *data;
93         struct lthread_queue *q = c->q;
94         size_t obj_size = c->obj_size;
95         int prealloc_size = c->prealloc_size;
96
97         data = _lthread_queue_remove(q);
98
99         if (data == NULL) {
100                 DIAG_COUNT_INC(c, prealloc);
101                 for (i = 0; i < prealloc_size; i++) {
102                         data =
103                             rte_zmalloc_socket(NULL, obj_size,
104                                         RTE_CACHE_LINE_SIZE,
105                                         rte_socket_id());
106                         if (data == NULL)
107                                 return NULL;
108
109                         DIAG_COUNT_INC(c, available);
110                         DIAG_COUNT_INC(c, capacity);
111                         _lthread_queue_insert_mp(q, data);
112                 }
113                 data = _lthread_queue_remove(q);
114         }
115         DIAG_COUNT_INC(c, rd);
116         DIAG_COUNT_DEC(c, available);
117         return data;
118 }
119
120 /*
121  * free an object to a cache
122  */
123 static inline void
124 _lthread_objcache_free(struct lthread_objcache *c, void *obj)
125 {
126         DIAG_COUNT_INC(c, wr);
127         DIAG_COUNT_INC(c, available);
128         _lthread_queue_insert_mp(c->q, obj);
129 }
130
131
132 #ifdef __cplusplus
133 }
134 #endif
135
136 #endif                          /* LTHREAD_OBJCACHE_H_ */