1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2015 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 #ifndef LTHREAD_OBJCACHE_H_ 34 #define LTHREAD_OBJCACHE_H_ 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #include <string.h> 41 42 #include <rte_per_lcore.h> 43 #include <rte_malloc.h> 44 #include <rte_memory.h> 45 46 #include "lthread_int.h" 47 #include "lthread_diag.h" 48 #include "lthread_queue.h" 49 50 51 RTE_DECLARE_PER_LCORE(struct lthread_sched *, this_sched); 52 53 struct lthread_objcache { 54 struct lthread_queue *q; 55 size_t obj_size; 56 int prealloc_size; 57 char name[LT_MAX_NAME_SIZE]; 58 59 DIAG_COUNT_DEFINE(rd); 60 DIAG_COUNT_DEFINE(wr); 61 DIAG_COUNT_DEFINE(prealloc); 62 DIAG_COUNT_DEFINE(capacity); 63 DIAG_COUNT_DEFINE(available); 64 }; 65 66 /* 67 * Create a cache 68 */ 69 static inline struct 70 lthread_objcache *_lthread_objcache_create(const char *name, 71 size_t obj_size, 72 int prealloc_size) 73 { 74 struct lthread_objcache *c = 75 rte_malloc_socket(NULL, sizeof(struct lthread_objcache), 76 RTE_CACHE_LINE_SIZE, 77 rte_socket_id()); 78 if (c == NULL) 79 return NULL; 80 81 c->q = _lthread_queue_create("cache queue"); 82 if (c->q == NULL) { 83 rte_free(c); 84 return NULL; 85 } 86 c->obj_size = obj_size; 87 c->prealloc_size = prealloc_size; 88 89 if (name != NULL) 90 strncpy(c->name, name, LT_MAX_NAME_SIZE); 91 c->name[sizeof(c->name)-1] = 0; 92 93 DIAG_COUNT_INIT(c, rd); 94 DIAG_COUNT_INIT(c, wr); 95 DIAG_COUNT_INIT(c, prealloc); 96 DIAG_COUNT_INIT(c, capacity); 97 DIAG_COUNT_INIT(c, available); 98 return c; 99 } 100 101 /* 102 * Destroy an objcache 103 */ 104 static inline int 105 _lthread_objcache_destroy(struct lthread_objcache *c) 106 { 107 if (_lthread_queue_destroy(c->q) == 0) { 108 rte_free(c); 109 return 0; 110 } 111 return -1; 112 } 113 114 /* 115 * Allocate an object from an object cache 116 */ 117 static inline void * 118 _lthread_objcache_alloc(struct lthread_objcache *c) 119 { 120 int i; 121 void *data; 122 struct lthread_queue *q = c->q; 123 size_t obj_size = c->obj_size; 124 int prealloc_size = c->prealloc_size; 125 126 data = _lthread_queue_remove(q); 127 128 if (data == NULL) { 129 DIAG_COUNT_INC(c, prealloc); 130 for (i = 0; i < prealloc_size; i++) { 131 data = 132 rte_zmalloc_socket(NULL, obj_size, 133 RTE_CACHE_LINE_SIZE, 134 rte_socket_id()); 135 if (data == NULL) 136 return NULL; 137 138 DIAG_COUNT_INC(c, available); 139 DIAG_COUNT_INC(c, capacity); 140 _lthread_queue_insert_mp(q, data); 141 } 142 data = _lthread_queue_remove(q); 143 } 144 DIAG_COUNT_INC(c, rd); 145 DIAG_COUNT_DEC(c, available); 146 return data; 147 } 148 149 /* 150 * free an object to a cache 151 */ 152 static inline void 153 _lthread_objcache_free(struct lthread_objcache *c, void *obj) 154 { 155 DIAG_COUNT_INC(c, wr); 156 DIAG_COUNT_INC(c, available); 157 _lthread_queue_insert_mp(c->q, obj); 158 } 159 160 161 #ifdef __cplusplus 162 } 163 #endif 164 165 #endif /* LTHREAD_OBJCACHE_H_ */ 166