00001 /* -*- mode:C++; c-basic-offset:4 -*- 00002 Shore-MT -- Multi-threaded port of the SHORE storage manager 00003 00004 Copyright (c) 2007-2009 00005 Data Intensive Applications and Systems Labaratory (DIAS) 00006 Ecole Polytechnique Federale de Lausanne 00007 00008 All Rights Reserved. 00009 00010 Permission to use, copy, modify and distribute this software and 00011 its documentation is hereby granted, provided that both the 00012 copyright notice and this permission notice appear in all copies of 00013 the software, derivative works or modified versions, and any 00014 portions thereof, and that both notices appear in supporting 00015 documentation. 00016 00017 This code is distributed in the hope that it will be useful, but 00018 WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS 00020 DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER 00021 RESULTING FROM THE USE OF THIS SOFTWARE. 00022 */ 00023 /*<std-header orig-src='shore' incl-file-exclusion='BLOCK_ALLOC_CPP'> 00024 00025 $Id: block_alloc.cpp,v 1.5 2010/09/23 13:52:36 nhall Exp $ 00026 00027 SHORE -- Scalable Heterogeneous Object REpository 00028 00029 Copyright (c) 1994-99 Computer Sciences Department, University of 00030 Wisconsin -- Madison 00031 All Rights Reserved. 00032 00033 Permission to use, copy, modify and distribute this software and its 00034 documentation is hereby granted, provided that both the copyright 00035 notice and this permission notice appear in all copies of the 00036 software, derivative works or modified versions, and any portions 00037 thereof, and that both notices appear in supporting documentation. 00038 00039 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY 00040 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS 00041 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND 00042 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 00043 00044 This software was developed with support by the Advanced Research 00045 Project Agency, ARPA order number 018 (formerly 8230), monitored by 00046 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518. 00047 Further funding for this work was provided by DARPA through 00048 Rome Research Laboratory Contract No. F30602-97-2-0247. 00049 00050 */ 00051 00052 #include "block_alloc.h" 00053 #include <cassert> 00054 00055 /**\cond skip */ 00056 00057 /* 00058 * dynpool is a thread-safe list into which 00059 * blocks are released and from which blocks are allocated. 00060 */ 00061 00062 dynpool::dynpool(size_t chip_size, size_t chip_count, size_t log2_block_size, size_t max_bytes) 00063 : _chip_size(chip_size) 00064 , _chip_count(chip_count) 00065 , _log2_block_size(log2_block_size) 00066 , _arr_end(0) 00067 { 00068 pthread_mutex_init(&_lock, 0); 00069 int err = _arr.init(max_bytes, size_t(1) << _log2_block_size); 00070 if(err) throw std::bad_alloc(); 00071 } 00072 00073 dynpool::~dynpool() { 00074 pthread_mutex_destroy(&_lock); 00075 _arr.fini(); 00076 } 00077 00078 dynpool::mblock* dynpool::_acquire_block() { 00079 mblock* rval; 00080 pthread_mutex_lock(&_lock); 00081 if(_free_list.empty()) { 00082 size_t block_size = size_t(1) << _log2_block_size; 00083 size_t new_end = _arr_end+block_size; 00084 int err = _arr.ensure_capacity(new_end); 00085 if(err) throw std::bad_alloc(); 00086 rval = new (_arr+_arr_end) mblock(_chip_size, _chip_count, block_size); 00087 _arr_end = new_end; 00088 } 00089 else { 00090 rval = _free_list.front(); 00091 _free_list.pop_front(); 00092 } 00093 pthread_mutex_unlock(&_lock); 00094 00095 return rval; 00096 } 00097 00098 void dynpool::_release_block(mblock* b) { 00099 pthread_mutex_lock(&_lock); 00100 _free_list.push_back(b); 00101 pthread_mutex_unlock(&_lock); 00102 } 00103 00104 bool dynpool::validate_pointer(void* ptr) { 00105 // no need for the mutex... dynarray only grows 00106 union { void* v; char* c; } u={ptr}; 00107 size_t offset = u.c - _arr; 00108 // An assertion here has been seen when the 00109 // user did this: 00110 // w_rc_t func() {} 00111 // and compiled w/o any warning (-Wall) to 00112 // tell him about the lack of a return value. Then 00113 // called the function. That gets us here. 00114 if((u.c < _arr) || (offset >= _arr_end)) { 00115 fprintf(stderr, 00116 "Assertion failure in dynpool: invalid pointer. %s\n", 00117 "(Did you fail to provide a return value for a w_rc_t-valued function?)"); 00118 } 00119 assert (u.c >= _arr); 00120 return offset < _arr_end; 00121 } 00122 /**\endcond skip */ 00123