00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
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
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
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
00177
00178
00179
00180
00181
00182
00183
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
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
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 }