00001 #include <string.h>
00002 #include <assert.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include "util.h"
00006 #include "vpr_types.h"
00007 #include "globals.h"
00008
00009
00010
00011
00012
00013
00014
00015
00016 int linenum;
00017
00018
00019
00020
00021 int
00022 limit_value(int cur,
00023 int max,
00024 const char *name)
00025 {
00026 if(cur > max)
00027 {
00028 printf(WARNTAG "%s is being limited from [%d] to [%d]\n",
00029 name, cur, max);
00030 return max;
00031 }
00032 return cur;
00033 }
00034
00035
00036
00037 char *
00038 my_strncpy(char *dest,
00039 const char *src,
00040 size_t size)
00041 {
00042
00043 size_t len = strlen(src);
00044
00045
00046 if(size <= len)
00047 len = (size - 1);
00048
00049
00050 memcpy(dest, src, len);
00051
00052
00053 dest[len] = '\0';
00054
00055 return dest;
00056 }
00057
00058
00059 FILE *
00060 my_fopen(const char *fname,
00061 const char *flag)
00062 {
00063 FILE *fp;
00064 int Len;
00065 char *new_fname = NULL;
00066
00067
00068 if(OutFilePrefix)
00069 {
00070 if(strchr(flag, 'w'))
00071 {
00072 Len = 1;
00073 Len += strlen(OutFilePrefix);
00074 Len += strlen(fname);
00075 new_fname = (char *)my_malloc(Len * sizeof(char));
00076 strcpy(new_fname, OutFilePrefix);
00077 strcat(new_fname, fname);
00078 fname = new_fname;
00079 }
00080 }
00081
00082 if(NULL == (fp = fopen(fname, flag)))
00083 {
00084 printf("Error opening file %s for %s access.\n", fname, flag);
00085 exit(1);
00086 }
00087
00088 if(new_fname)
00089 free(new_fname);
00090
00091 return (fp);
00092 }
00093
00094
00095 char *
00096 my_strdup(const char *str)
00097 {
00098 int Len;
00099 char *Dst;
00100
00101 Len = 1 + strlen(str);
00102 Dst = (char *)my_malloc(Len * sizeof(char));
00103 memcpy(Dst, str, Len);
00104
00105 return Dst;
00106 }
00107
00108
00109 int
00110 my_atoi(const char *str)
00111 {
00112
00113
00114
00115
00116 if(str[0] < '0' || str[0] > '9')
00117 {
00118 if(!(str[0] == '-' && str[1] >= '0' && str[1] <= '9'))
00119 {
00120 printf(ERRTAG "expected number instead of '%s'.\n", str);
00121 exit(1);
00122 }
00123 }
00124 return (atoi(str));
00125 }
00126
00127
00128 void *
00129 my_calloc(size_t nelem,
00130 size_t size)
00131 {
00132
00133 void *ret;
00134
00135 if((ret = calloc(nelem, size)) == NULL)
00136 {
00137 fprintf(stderr, "Error: Unable to calloc memory. Aborting.\n");
00138 exit(1);
00139 }
00140 return (ret);
00141 }
00142
00143
00144 void *
00145 my_malloc(size_t size)
00146 {
00147
00148 void *ret;
00149
00150 if((ret = malloc(size)) == NULL)
00151 {
00152 fprintf(stderr, "Error: Unable to malloc memory. Aborting.\n");
00153 abort();
00154 exit(1);
00155 }
00156 return (ret);
00157 }
00158
00159
00160
00161 void *
00162 my_realloc(void *ptr,
00163 size_t size)
00164 {
00165
00166 void *ret;
00167
00168 if(size <= 0)
00169 {
00170 printf("reallocating of size <= 0.\n");
00171 }
00172
00173 ret = realloc(ptr, size);
00174 if(NULL == ret)
00175 {
00176 printf(ERRTAG "Unable to realloc memory. Aborting. "
00177 "ptr=%p, Size=%d.\n", ptr, size);
00178 if(ptr == NULL)
00179 {
00180 printf(ERRTAG "my_realloc: ptr == NULL. Aborting.\n");
00181 }
00182 exit(1);
00183 }
00184 return (ret);
00185 }
00186
00187
00188 void *
00189 my_chunk_malloc(size_t size,
00190 struct s_linked_vptr **chunk_ptr_head,
00191 int *mem_avail_ptr,
00192 char **next_mem_loc_ptr)
00193 {
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 typedef long Align;
00217
00218 #define CHUNK_SIZE 32768
00219 #define FRAGMENT_THRESHOLD 100
00220
00221 char *tmp_ptr;
00222 int aligned_size;
00223
00224 assert(*mem_avail_ptr >= 0);
00225
00226 if((size_t) (*mem_avail_ptr) < size)
00227 {
00228 if(size > CHUNK_SIZE)
00229 {
00230 tmp_ptr = my_malloc(size);
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 if(chunk_ptr_head != NULL)
00241 *chunk_ptr_head =
00242 insert_in_vptr_list(*chunk_ptr_head, tmp_ptr);
00243 return (tmp_ptr);
00244 }
00245
00246 if(*mem_avail_ptr < FRAGMENT_THRESHOLD)
00247 {
00248 *next_mem_loc_ptr = my_malloc(CHUNK_SIZE);
00249 *mem_avail_ptr = CHUNK_SIZE;
00250 if(chunk_ptr_head != NULL)
00251 *chunk_ptr_head = insert_in_vptr_list(*chunk_ptr_head,
00252 *next_mem_loc_ptr);
00253 }
00254
00255
00256
00257
00258
00259 else
00260 {
00261 tmp_ptr = my_malloc(size);
00262 if(chunk_ptr_head != NULL)
00263 *chunk_ptr_head =
00264 insert_in_vptr_list(*chunk_ptr_head, tmp_ptr);
00265 return (tmp_ptr);
00266 }
00267 }
00268
00269
00270
00271
00272 if(size % sizeof(Align) == 0)
00273 {
00274 aligned_size = size;
00275 }
00276 else
00277 {
00278 aligned_size = size + sizeof(Align) - size % sizeof(Align);
00279 }
00280
00281 tmp_ptr = *next_mem_loc_ptr;
00282 *next_mem_loc_ptr += aligned_size;
00283 *mem_avail_ptr -= aligned_size;
00284 return (tmp_ptr);
00285 }
00286
00287
00288 void
00289 free_chunk_memory(struct s_linked_vptr *chunk_ptr_head)
00290 {
00291
00292
00293
00294 struct s_linked_vptr *curr_ptr, *prev_ptr;
00295
00296 curr_ptr = chunk_ptr_head;
00297
00298 while(curr_ptr != NULL)
00299 {
00300 free(curr_ptr->data_vptr);
00301 prev_ptr = curr_ptr;
00302 curr_ptr = curr_ptr->next;
00303 free(prev_ptr);
00304 }
00305 }
00306
00307
00308 struct s_linked_vptr *
00309 insert_in_vptr_list(struct s_linked_vptr *head,
00310 void *vptr_to_add)
00311 {
00312
00313
00314
00315
00316 struct s_linked_vptr *linked_vptr;
00317
00318 linked_vptr = (struct s_linked_vptr *)my_malloc(sizeof(struct
00319 s_linked_vptr));
00320
00321 linked_vptr->data_vptr = vptr_to_add;
00322 linked_vptr->next = head;
00323 return (linked_vptr);
00324 }
00325
00326
00327 t_linked_int *
00328 insert_in_int_list(t_linked_int * head,
00329 int data,
00330 t_linked_int ** free_list_head_ptr)
00331 {
00332
00333
00334
00335
00336
00337
00338 t_linked_int *linked_int;
00339
00340 if(*free_list_head_ptr != NULL)
00341 {
00342 linked_int = *free_list_head_ptr;
00343 *free_list_head_ptr = linked_int->next;
00344 }
00345 else
00346 {
00347 linked_int = (t_linked_int *) my_malloc(sizeof(t_linked_int));
00348 }
00349
00350 linked_int->data = data;
00351 linked_int->next = head;
00352 return (linked_int);
00353 }
00354
00355
00356 void
00357 free_int_list(t_linked_int ** int_list_head_ptr)
00358 {
00359
00360
00361
00362
00363 t_linked_int *linked_int, *next_linked_int;
00364
00365 linked_int = *int_list_head_ptr;
00366
00367 while(linked_int != NULL)
00368 {
00369 next_linked_int = linked_int->next;
00370 free(linked_int);
00371 linked_int = next_linked_int;
00372 }
00373
00374 *int_list_head_ptr = NULL;
00375 }
00376
00377
00378 void
00379 alloc_ivector_and_copy_int_list(t_linked_int ** list_head_ptr,
00380 int num_items,
00381 struct s_ivec *ivec,
00382 t_linked_int ** free_list_head_ptr)
00383 {
00384
00385
00386
00387
00388
00389
00390 t_linked_int *linked_int, *list_head;
00391 int i, *list;
00392
00393 list_head = *list_head_ptr;
00394
00395 if(num_items == 0)
00396 {
00397 ivec->nelem = 0;
00398 ivec->list = NULL;
00399
00400 if(list_head != NULL)
00401 {
00402 printf(ERRTAG
00403 "alloc_ivector_and_copy_int_list: Copied %d elements, "
00404 "but list at %p contains more.\n", num_items,
00405 (void *)list_head);
00406 exit(1);
00407 }
00408 return;
00409 }
00410
00411 ivec->nelem = num_items;
00412 list = (int *)my_malloc(num_items * sizeof(int));
00413 ivec->list = list;
00414 linked_int = list_head;
00415
00416 for(i = 0; i < num_items - 1; i++)
00417 {
00418 list[i] = linked_int->data;
00419 linked_int = linked_int->next;
00420 }
00421
00422 list[num_items - 1] = linked_int->data;
00423
00424 if(linked_int->next != NULL)
00425 {
00426 printf
00427 ("Error in alloc_ivector_and_copy_int_list:\n Copied %d elements, "
00428 "but list at %p contains more.\n", num_items,
00429 (void *)list_head);
00430 exit(1);
00431 }
00432
00433 linked_int->next = *free_list_head_ptr;
00434 *free_list_head_ptr = list_head;
00435 *list_head_ptr = NULL;
00436 }
00437
00438
00439 static int cont;
00440
00441 char *
00442 my_fgets(char *buf,
00443 int max_size,
00444 FILE * fp)
00445 {
00446
00447
00448
00449
00450 char *val;
00451 int i;
00452
00453 cont = 0;
00454 val = fgets(buf, max_size, fp);
00455 linenum++;
00456 if(val == NULL)
00457 return (val);
00458
00459
00460
00461
00462 for(i = 0; i < max_size; i++)
00463 {
00464 if(buf[i] == '\n')
00465 break;
00466 if(buf[i] == '\0')
00467 {
00468 printf
00469 ("Error on line %d -- line is too long for input buffer.\n",
00470 linenum);
00471 printf("All lines must be at most %d characters long.\n",
00472 BUFSIZE - 2);
00473 printf
00474 ("The problem could also be caused by a missing newline.\n");
00475 exit(1);
00476 }
00477 }
00478
00479
00480 for(i = 0; i < max_size && buf[i] != '\0'; i++)
00481 {
00482 if(buf[i] == '#')
00483 {
00484 buf[i] = '\0';
00485 break;
00486 }
00487 }
00488
00489 if(i < 2)
00490 return (val);
00491 if(buf[i - 1] == '\n' && buf[i - 2] == '\\')
00492 {
00493 cont = 1;
00494 buf[i - 2] = '\n';
00495 buf[i - 1] = '\0';
00496 }
00497 return (val);
00498 }
00499
00500
00501 char *
00502 my_strtok(char *ptr,
00503 char *tokens,
00504 FILE * fp,
00505 char *buf)
00506 {
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 char *val;
00518
00519 val = strtok(ptr, tokens);
00520 for(;;)
00521 {
00522 if(val != NULL || cont == 0)
00523 return (val);
00524
00525
00526 if(my_fgets(buf, BUFSIZE, fp) == NULL)
00527 return (NULL);
00528
00529 val = strtok(buf, tokens);
00530 }
00531 }
00532
00533
00534 void
00535 free_ivec_vector(struct s_ivec *ivec_vector,
00536 int nrmin,
00537 int nrmax)
00538 {
00539
00540
00541
00542 int i;
00543
00544 for(i = nrmin; i <= nrmax; i++)
00545 if(ivec_vector[i].nelem != 0)
00546 free(ivec_vector[i].list);
00547
00548 free(ivec_vector + nrmin);
00549 }
00550
00551
00552 void
00553 free_ivec_matrix(struct s_ivec **ivec_matrix,
00554 int nrmin,
00555 int nrmax,
00556 int ncmin,
00557 int ncmax)
00558 {
00559
00560
00561
00562 int i, j;
00563
00564 for(i = nrmin; i <= nrmax; i++)
00565 {
00566 for(j = ncmin; j <= ncmax; j++)
00567 {
00568 if(ivec_matrix[i][j].nelem != 0)
00569 {
00570 free(ivec_matrix[i][j].list);
00571 }
00572 }
00573 }
00574
00575 free_matrix(ivec_matrix, nrmin, nrmax, ncmin, sizeof(struct s_ivec));
00576 }
00577
00578
00579 void
00580 free_ivec_matrix3(struct s_ivec ***ivec_matrix3,
00581 int nrmin,
00582 int nrmax,
00583 int ncmin,
00584 int ncmax,
00585 int ndmin,
00586 int ndmax)
00587 {
00588
00589
00590
00591 int i, j, k;
00592
00593 for(i = nrmin; i <= nrmax; i++)
00594 {
00595 for(j = ncmin; j <= ncmax; j++)
00596 {
00597 for(k = ndmin; k <= ndmax; k++)
00598 {
00599 if(ivec_matrix3[i][j][k].nelem != 0)
00600 {
00601 free(ivec_matrix3[i][j][k].list);
00602 }
00603 }
00604 }
00605 }
00606
00607 free_matrix3(ivec_matrix3, nrmin, nrmax, ncmin, ncmax, ndmin,
00608 sizeof(struct s_ivec));
00609 }
00610
00611
00612 void **
00613 alloc_matrix(int nrmin,
00614 int nrmax,
00615 int ncmin,
00616 int ncmax,
00617 size_t elsize)
00618 {
00619
00620
00621
00622
00623
00624
00625 int i;
00626 char **cptr;
00627
00628 cptr = (char **)my_malloc((nrmax - nrmin + 1) * sizeof(char *));
00629 cptr -= nrmin;
00630 for(i = nrmin; i <= nrmax; i++)
00631 {
00632 cptr[i] = (char *)my_malloc((ncmax - ncmin + 1) * elsize);
00633 cptr[i] -= ncmin * elsize / sizeof(char);
00634 }
00635 return ((void **)cptr);
00636 }
00637
00638
00639
00640
00641
00642 void
00643 free_matrix(void *vptr,
00644 int nrmin,
00645 int nrmax,
00646 int ncmin,
00647 size_t elsize)
00648 {
00649
00650 int i;
00651 char **cptr;
00652
00653 cptr = (char **)vptr;
00654
00655 for(i = nrmin; i <= nrmax; i++)
00656 free(cptr[i] + ncmin * elsize / sizeof(char));
00657 free(cptr + nrmin);
00658 }
00659
00660
00661 void ***
00662 alloc_matrix3(int nrmin,
00663 int nrmax,
00664 int ncmin,
00665 int ncmax,
00666 int ndmin,
00667 int ndmax,
00668 size_t elsize)
00669 {
00670
00671
00672
00673
00674
00675
00676
00677 int i, j;
00678 char ***cptr;
00679
00680 cptr = (char ***)my_malloc((nrmax - nrmin + 1) * sizeof(char **));
00681 cptr -= nrmin;
00682 for(i = nrmin; i <= nrmax; i++)
00683 {
00684 cptr[i] =
00685 (char **)my_malloc((ncmax - ncmin + 1) * sizeof(char *));
00686 cptr[i] -= ncmin;
00687 for(j = ncmin; j <= ncmax; j++)
00688 {
00689 cptr[i][j] =
00690 (char *)my_malloc((ndmax - ndmin + 1) * elsize);
00691 cptr[i][j] -= ndmin * elsize / sizeof(char);
00692 }
00693 }
00694 return ((void ***)cptr);
00695 }
00696
00697 void ****
00698 alloc_matrix4(int nrmin,
00699 int nrmax,
00700 int ncmin,
00701 int ncmax,
00702 int ndmin,
00703 int ndmax,
00704 int nemin,
00705 int nemax,
00706 size_t elsize)
00707 {
00708
00709
00710
00711
00712
00713
00714
00715 int i, j, k;
00716 char ****cptr;
00717
00718 cptr = (char ****)my_malloc((nrmax - nrmin + 1) * sizeof(char ***));
00719 cptr -= nrmin;
00720 for(i = nrmin; i <= nrmax; i++)
00721 {
00722 cptr[i] =
00723 (char ***)my_malloc((ncmax - ncmin + 1) * sizeof(char **));
00724 cptr[i] -= ncmin;
00725 for(j = ncmin; j <= ncmax; j++)
00726 {
00727 cptr[i][j] =
00728 (char **)my_malloc((ndmax - ndmin + 1) *
00729 sizeof(char *));
00730 cptr[i][j] -= ndmin;
00731 for(k = ndmin; k <= ndmax; k++)
00732 {
00733 cptr[i][j][k] =
00734 (char *)my_malloc((nemax - nemin + 1) *
00735 elsize);
00736 cptr[i][j][k] -= nemin * elsize / sizeof(char);
00737 }
00738 }
00739 }
00740 return ((void ****)cptr);
00741 }
00742
00743 void
00744 print_int_matrix3(int ***vptr,
00745 int nrmin,
00746 int nrmax,
00747 int ncmin,
00748 int ncmax,
00749 int ndmin,
00750 int ndmax,
00751 char *file)
00752 {
00753 FILE *outfile;
00754 int i, j, k;
00755
00756 outfile = my_fopen(file, "w");
00757
00758 for(k = nrmin; k <= nrmax; ++k)
00759 {
00760 fprintf(outfile, "Plane %d\n", k);
00761 for(j = ncmin; j <= ncmax; ++j)
00762 {
00763 for(i = ndmin; i <= ndmax; ++i)
00764 {
00765 fprintf(outfile, "%d ", vptr[k][j][i]);
00766 }
00767 fprintf(outfile, "\n");
00768 }
00769 fprintf(outfile, "\n");
00770 }
00771
00772 fclose(outfile);
00773 }
00774
00775
00776 void
00777 free_matrix3(void *vptr,
00778 int nrmin,
00779 int nrmax,
00780 int ncmin,
00781 int ncmax,
00782 int ndmin,
00783 size_t elsize)
00784 {
00785
00786 int i, j;
00787 char ***cptr;
00788
00789 cptr = (char ***)vptr;
00790
00791 for(i = nrmin; i <= nrmax; i++)
00792 {
00793 for(j = ncmin; j <= ncmax; j++)
00794 free(cptr[i][j] + ndmin * elsize / sizeof(char));
00795 free(cptr[i] + ncmin);
00796 }
00797 free(cptr + nrmin);
00798 }
00799
00800 void
00801 free_matrix4(void *vptr,
00802 int nrmin,
00803 int nrmax,
00804 int ncmin,
00805 int ncmax,
00806 int ndmin,
00807 int ndmax,
00808 int nemin,
00809 size_t elsize)
00810 {
00811
00812 int i, j, k;
00813 char ****cptr;
00814
00815 cptr = (char ****)vptr;
00816
00817 for(i = nrmin; i <= nrmax; i++)
00818 {
00819 for(j = ncmin; j <= ncmax; j++)
00820 {
00821 for(k = ndmin; k <= ndmax; k++)
00822 free(cptr[i][j][k] + nemin * elsize / sizeof(char));
00823 free(cptr[i][j] + ndmin * elsize / sizeof(char));
00824 }
00825 free(cptr[i] + ncmin);
00826 }
00827 free(cptr + nrmin);
00828 }
00829
00830
00831
00832
00833
00834 #define IA 1103515245u
00835 #define IC 12345u
00836 #define IM 2147483648u
00837 #define CHECK_RAND
00838
00839 static unsigned int current_random = 0;
00840
00841
00842 void
00843 my_srandom(int seed)
00844 {
00845 current_random = (unsigned int)seed;
00846 }
00847
00848
00849 int
00850 my_irand(int imax)
00851 {
00852
00853
00854
00855 int ival;
00856
00857
00858 current_random = current_random * IA + IC;
00859 ival = current_random & (IM - 1);
00860 ival = (int)((float)ival * (float)(imax + 0.999) / (float)IM);
00861
00862 #ifdef CHECK_RAND
00863 if((ival < 0) || (ival > imax))
00864 {
00865 printf("Bad value in my_irand, imax = %d ival = %d\n", imax,
00866 ival);
00867 exit(1);
00868 }
00869 #endif
00870
00871 return (ival);
00872 }
00873
00874
00875 float
00876 my_frand(void)
00877 {
00878
00879
00880
00881 float fval;
00882 int ival;
00883
00884 current_random = current_random * IA + IC;
00885 ival = current_random & (IM - 1);
00886 fval = (float)ival / (float)IM;
00887
00888 #ifdef CHECK_RAND
00889 if((fval < 0) || (fval > 1.))
00890 {
00891 printf("Bad value in my_frand, fval = %g\n", fval);
00892 exit(1);
00893 }
00894 #endif
00895
00896 return (fval);
00897 }