alloc-address.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  * 
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Daedalus Research
00017  *  Group at the University of California Berkeley.
00018  * 4. Neither the name of the University nor of the Research Group may be
00019  *    used to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  * 
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/alloc-address.cc,v 1.10 2000/09/14 18:19:25 haoboy Exp $
00035  */
00036 
00037 /* functions invoked to allocate bits to the ns-address space */
00038 
00039 #include <stdlib.h>
00040 #include <assert.h>
00041 #include "config.h"
00042 #include <tclcl.h>
00043 
00044 
00045 class AllocAddr : public TclObject {
00046 public:
00047     AllocAddr();
00048     ~AllocAddr();
00049     int command(int argc, const char*const* argv);
00050 protected:
00051     void get_mask(nsmask_t *mask, int fieldsize);
00052     void alloc(int n);
00053     bool check_size(int n);
00054     bool find_free(int len, int *pos);
00055     bool test(int which);
00056     void set_field(int offset, int len, nsmask_t *mask, int *shift);
00057     void free_field(int len);
00058     void mark(int i);
00059     int size_;
00060     int *bitmap_;
00061 };
00062 
00063 
00064 class AllocAddrClass : public TclClass {
00065 public:
00066     AllocAddrClass() : TclClass("AllocAddr") {}
00067     TclObject* create(int, const char*const*) {
00068         return (new AllocAddr());
00069     }
00070 } AllocAddr_class;
00071 
00072 
00073 
00074 int AllocAddr::command(int argc, const char*const* argv)
00075 {
00076     int offset,
00077         addrsize,
00078         shift,
00079         fieldlen;
00080     nsmask_t mask;
00081 
00082     Tcl& tcl = Tcl::instance();
00083 
00084     if (argc == 3) {
00085         if (strcmp(argv[1], "freebit") == 0) {
00086             fieldlen = atoi(argv[2]);
00087             assert(fieldlen > 0);
00088             free_field(fieldlen);
00089             return (TCL_OK);
00090         }
00091     }
00092 
00093 
00094     else if (argc == 4) {
00095         if (strcmp(argv[1], "setbit") == 0) {
00096             fieldlen = atoi(argv[2]);
00097             addrsize = atoi(argv[3]);
00098             if (!check_size(addrsize)) {
00099                 tcl.result("setbit: Size_ increased: Reallocate bits");
00100                 return (TCL_ERROR);
00101             }
00102             if (!find_free(fieldlen, &offset)) {
00103                 tcl.result("setbit: no contiguous space found\n");
00104                 return (TCL_ERROR);
00105             }
00106             set_field(offset, fieldlen, &mask, &shift);
00107             // TESTING
00108             tcl.resultf("%d %d", mask, shift);
00109             return (TCL_OK);
00110         }
00111     }
00112     else if (argc == 5) {
00113         int oldfldlen;
00114         if (strcmp(argv[1], "expand-port") == 0) {
00115             fieldlen = atoi(argv[2]);
00116             addrsize = atoi(argv[3]);
00117             oldfldlen = atoi(argv[4]);
00118             if (!check_size(addrsize)) {
00119                 tcl.result("expand-port: Size_ increased: Reallocate bits");
00120                 return (TCL_ERROR);
00121             }
00122             if (!find_free(fieldlen, &offset)) {
00123                 tcl.result("expand-port: no contiguous space found\n");
00124                 return (TCL_ERROR);
00125             }
00126             int i, k;
00127             for (i = offset, k = 0; k < fieldlen; k++, i--) {
00128                 bitmap_[i] = 1;
00129             }
00130             shift = offset - (fieldlen - 1);
00131             get_mask(&mask, fieldlen + oldfldlen);
00132             // TESTING
00133             tcl.resultf("%d %d", mask, shift);
00134             return (TCL_OK);
00135         }
00136     }
00137     return TclObject::command(argc, argv);
00138 }
00139 
00140 
00141 AllocAddr::AllocAddr()
00142 {
00143     size_ = 0;
00144     bitmap_ = 0;
00145 
00146 }
00147 
00148 AllocAddr::~AllocAddr()
00149 {
00150     delete [] bitmap_;
00151 
00152 }
00153 
00154 void AllocAddr::alloc(int n)
00155 {
00156     size_ = n;
00157     bitmap_ = new int[n];
00158     for (int i=0; i < n; i++)
00159         bitmap_[i] = 0;
00160 }
00161 
00162 
00163 bool AllocAddr::check_size(int n)
00164 {
00165     if (n <= size_)
00166         return 1;
00167     assert (n > 0);
00168     if (size_ == 0) {
00169         alloc(n);
00170         return 1;
00171     }
00172     if (n > size_) 
00173         return 0;
00174     return 1;
00175 
00176     // this check is no longer needed, as now bits are re-allocated every time
00177     // the size changes.
00178     //     int *old = bitmap_;
00179     //     int osize = size_;
00180     //     alloc(n);
00181     //     for (int i = 0; i < osize; i++) 
00182     //  bitmap_[i] = old[i];
00183     //     delete [] old;
00184 }
00185 
00186 void AllocAddr::mark(int i)
00187 {
00188     bitmap_[i] = 1;
00189 }
00190 
00191 
00192 void AllocAddr::get_mask(nsmask_t *mask, int fieldsize)
00193 {
00194     // int temp = (int)(pow(2, (double)fieldsize));
00195     *mask = (1 << fieldsize) - 1;
00196 }
00197 
00198 
00199 bool AllocAddr::test(int which)
00200 {
00201     assert(which <= size_);
00202     if (bitmap_[which] == 1)
00203         return TRUE;
00204     else
00205         return FALSE;
00206 }
00207 
00208 
00209 bool AllocAddr::find_free(int len, int *pos) 
00210 {
00211     int count = 0;
00212     int temp = 0;
00213 
00214     for (int i = (size_ - 1); i >= 0; i--)
00215         if (!test(i)) {
00216             /**** check if n contiguous bits are free ****/
00217             temp = i;
00218             for (int k = 0; (k < len) && (i >=0); k++, i--){
00219                 if(test(i)) {
00220                     count = 0;
00221                     break;
00222                 }
00223                 count++;
00224             }
00225             if (count == len) {
00226                 *pos = temp;
00227                 return 1;
00228             }
00229         }
00230     return 0;
00231 }
00232 
00233 
00234 void AllocAddr::set_field(int offset, int len, nsmask_t *mask, int *shift)
00235 {
00236     int i, k;
00237 
00238     for (k = 0, i = offset; k < len; k++, i--) {
00239         bitmap_[i] = 1; 
00240     }
00241     *shift = offset - (len-1);
00242     get_mask(mask, len);
00243 }
00244 
00245 
00246 void AllocAddr::free_field(int len)
00247 {
00248     int count = 0;
00249 
00250     for (int i = 0; i < size_; i++) {
00251         if (test(i)) {
00252             bitmap_[i] = 0;
00253             count++;
00254         }
00255         if (count == len)
00256             break;
00257     }
00258 }

Generated on Tue Mar 6 16:47:43 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6