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