block_alloc.cpp

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 

Generated on Thu Dec 9 08:42:27 2010 for Shore Storage Manager by  doxygen 1.4.7