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 #include <string.h> 37 38 #include <rte_per_lcore.h> 39 #include <rte_malloc.h> 40 #include <rte_memory.h> 41 42 #include "lthread_int.h" 43 #include "lthread_diag.h" 44 #include "lthread_queue.h" 45 46 47 RTE_DECLARE_PER_LCORE(struct lthread_sched *, this_sched); 48 49 struct lthread_objcache { 50 struct lthread_queue *q; 51 size_t obj_size; 52 int prealloc_size; 53 char name[LT_MAX_NAME_SIZE]; 54 55 DIAG_COUNT_DEFINE(rd); 56 DIAG_COUNT_DEFINE(wr); 57 DIAG_COUNT_DEFINE(prealloc); 58 DIAG_COUNT_DEFINE(capacity); 59 DIAG_COUNT_DEFINE(available); 60 }; 61 62 /* 63 * Create a cache 64 */ 65 static inline struct 66 lthread_objcache *_lthread_objcache_create(const char *name, 67 size_t obj_size, 68 int prealloc_size) 69 { 70 struct lthread_objcache *c = 71 rte_malloc_socket(NULL, sizeof(struct lthread_objcache), 72 RTE_CACHE_LINE_SIZE, 73 rte_socket_id()); 74 if (c == NULL) 75 return NULL; 76 77 c->q = _lthread_queue_create("cache queue"); 78 if (c->q == NULL) { 79 rte_free(c); 80 return NULL; 81 } 82 c->obj_size = obj_size; 83 c->prealloc_size = prealloc_size; 84 85 if (name != NULL) 86 strncpy(c->name, name, LT_MAX_NAME_SIZE); 87 c->name[sizeof(c->name)-1] = 0; 88 89 DIAG_COUNT_INIT(c, rd); 90 DIAG_COUNT_INIT(c, wr); 91 DIAG_COUNT_INIT(c, prealloc); 92 DIAG_COUNT_INIT(c, capacity); 93 DIAG_COUNT_INIT(c, available); 94 return c; 95 } 96 97 /* 98 * Destroy an objcache 99 */ 100 static inline int 101 _lthread_objcache_destroy(struct lthread_objcache *c) 102 { 103 if (_lthread_queue_destroy(c->q) == 0) { 104 rte_free(c); 105 return 0; 106 } 107 return -1; 108 } 109 110 /* 111 * Allocate an object from an object cache 112 */ 113 static inline void * 114 _lthread_objcache_alloc(struct lthread_objcache *c) 115 { 116 int i; 117 void *data; 118 struct lthread_queue *q = c->q; 119 size_t obj_size = c->obj_size; 120 int prealloc_size = c->prealloc_size; 121 122 data = _lthread_queue_remove(q); 123 124 if (data == NULL) { 125 DIAG_COUNT_INC(c, prealloc); 126 for (i = 0; i < prealloc_size; i++) { 127 data = 128 rte_zmalloc_socket(NULL, obj_size, 129 RTE_CACHE_LINE_SIZE, 130 rte_socket_id()); 131 if (data == NULL) 132 return NULL; 133 134 DIAG_COUNT_INC(c, available); 135 DIAG_COUNT_INC(c, capacity); 136 _lthread_queue_insert_mp(q, data); 137 } 138 data = _lthread_queue_remove(q); 139 } 140 DIAG_COUNT_INC(c, rd); 141 DIAG_COUNT_DEC(c, available); 142 return data; 143 } 144 145 /* 146 * free an object to a cache 147 */ 148 static inline void 149 _lthread_objcache_free(struct lthread_objcache *c, void *obj) 150 { 151 DIAG_COUNT_INC(c, wr); 152 DIAG_COUNT_INC(c, available); 153 _lthread_queue_insert_mp(c->q, obj); 154 } 155 156 157 158 #endif /* LTHREAD_OBJCACHE_H_ */ 159