cvmx-zone.c revision 210286
1/***********************license start*************** 2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 * 23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39 40 41 42 43 44/** 45 * @file 46 * 47 * Support library for the Zone Allocator. 48 * 49 * <hr>$Revision: 41586 $<hr> 50 */ 51 52 53#include "cvmx-config.h" 54#include "cvmx.h" 55#include "cvmx-spinlock.h" 56#include "cvmx-malloc.h" 57 58 59 60 61cvmx_zone_t cvmx_zone_create_from_addr(char *name, uint32_t elem_size, uint32_t num_elem, 62 void* mem_ptr, uint64_t mem_size, uint32_t flags) 63{ 64 cvmx_zone_t zone; 65 unsigned int i; 66 67 if ((unsigned long)mem_ptr & (sizeof(void *) -1)) 68 { 69 return(NULL); //invalid alignment 70 } 71 if (mem_size < sizeof(struct cvmx_zone) + elem_size * num_elem) 72 { 73 return(NULL); // not enough room 74 } 75 76 zone = (cvmx_zone_t) ((char *)mem_ptr + elem_size * num_elem); 77 zone->elem_size = elem_size; 78 zone->num_elem = num_elem; 79 zone->name = name; 80 zone->align = 0; // not used 81 zone->baseptr = NULL; 82 zone->freelist = NULL; 83 zone->lock.value = CVMX_SPINLOCK_UNLOCKED_VAL; 84 85 zone->baseptr = (char *)mem_ptr; 86 87 for(i=0;i<num_elem;i++) 88 { 89 *(void **)(zone->baseptr + (i*elem_size)) = zone->freelist; 90 zone->freelist = (void *)(zone->baseptr + (i*elem_size)); 91 } 92 93 return(zone); 94 95} 96 97cvmx_zone_t cvmx_zone_create_from_arena(char *name, uint32_t elem_size, uint32_t num_elem, uint32_t align, cvmx_arena_list_t arena_list, uint32_t flags) 98{ 99 unsigned int i; 100 cvmx_zone_t zone; 101 102 zone = (cvmx_zone_t)cvmx_malloc(arena_list, sizeof(struct cvmx_zone)); 103 104 if (NULL == zone) 105 { 106 return(NULL); 107 } 108 zone->elem_size = elem_size; 109 zone->num_elem = num_elem; 110 zone->name = name; 111 zone->align = align; 112 zone->baseptr = NULL; 113 zone->freelist = NULL; 114 zone->lock.value = CVMX_SPINLOCK_UNLOCKED_VAL; 115 116 zone->baseptr = (char *)cvmx_memalign(arena_list, align, num_elem * elem_size); 117 if (NULL == zone->baseptr) 118 { 119 return(NULL); 120 } 121 122 for(i=0;i<num_elem;i++) 123 { 124 *(void **)(zone->baseptr + (i*elem_size)) = zone->freelist; 125 zone->freelist = (void *)(zone->baseptr + (i*elem_size)); 126 } 127 128 return(zone); 129 130} 131 132 133 134void * cvmx_zone_alloc(cvmx_zone_t zone, uint32_t flags) 135{ 136 cvmx_zone_t item; 137 138 assert(zone != NULL); 139 assert(zone->baseptr != NULL); 140 cvmx_spinlock_lock(&zone->lock); 141 142 item = (cvmx_zone_t)zone->freelist; 143 if(item != NULL) 144 { 145 zone->freelist = *(void **)item; 146 } 147 else 148 { 149// cvmx_dprintf("No more elements in zone %s\n", zone->name); 150 } 151 152 cvmx_spinlock_unlock(&zone->lock); 153 return(item); 154} 155 156void cvmx_zone_free(cvmx_zone_t zone, void *ptr) 157{ 158 159 assert(zone != NULL); 160 assert(zone->baseptr != NULL); 161 assert((unsigned long)ptr - (unsigned long)zone->baseptr < zone->num_elem * zone->elem_size); 162 163 cvmx_spinlock_lock(&zone->lock); 164 *(void **)ptr = zone->freelist; 165 zone->freelist = ptr; 166 cvmx_spinlock_unlock(&zone->lock); 167} 168 169 170