⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 VPR布局布线源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>#include <assert.h>#include <stdio.h>#include <stdlib.h>#include "util.h"#include "vpr_types.h"#include "globals.h"/* This file contains utility functions widely used in * * my programs.  Many are simply versions of file and  * * memory grabbing routines that take the same         * * arguments as the standard library ones, but exit    * * the program if they find an error condition.        */int linenum;			/* Line in file being parsed. *//* Returns the min of cur and max. If cur > max, a warning * is emitted. */intlimit_value(int cur,	    int max,	    const char *name){    if(cur > max)	{	    printf(WARNTAG "%s is being limited from [%d] to [%d]\n",		   name, cur, max);	    return max;	}    return cur;}/* An alternate for strncpy since strncpy doesn't work as most * people would expect. This ensures null termination */char *my_strncpy(char *dest,	   const char *src,	   size_t size){    /* Find string's length */    size_t len = strlen(src);    /* Cap length at (num - 1) to leave room for \0 */    if(size <= len)	len = (size - 1);    /* Copy as much of string as we can fit */    memcpy(dest, src, len);    /* explicit null termination */    dest[len] = '\0';    return dest;}/* Uses global var 'OutFilePrefix' */FILE *my_fopen(const char *fname,	 const char *flag){    FILE *fp;    int Len;    char *new_fname = NULL;    /* Appends a prefix string for output files */    if(OutFilePrefix)	{	    if(strchr(flag, 'w'))		{		    Len = 1;	/* NULL char */		    Len += strlen(OutFilePrefix);		    Len += strlen(fname);		    new_fname = (char *)my_malloc(Len * sizeof(char));		    strcpy(new_fname, OutFilePrefix);		    strcat(new_fname, fname);		    fname = new_fname;		}	}    if(NULL == (fp = fopen(fname, flag)))	{	    printf("Error opening file %s for %s access.\n", fname, flag);	    exit(1);	}    if(new_fname)	free(new_fname);    return (fp);}char *my_strdup(const char *str){    int Len;    char *Dst;    Len = 1 + strlen(str);    Dst = (char *)my_malloc(Len * sizeof(char));    memcpy(Dst, str, Len);    return Dst;}intmy_atoi(const char *str){/* Returns the integer represented by the first part of the character       * * string.                                              */    if(str[0] < '0' || str[0] > '9')	{	    if(!(str[0] == '-' && str[1] >= '0' && str[1] <= '9'))		{		    printf(ERRTAG "expected number instead of '%s'.\n", str);		    exit(1);		}	}    return (atoi(str));}void *my_calloc(size_t nelem,	  size_t size){    void *ret;    if((ret = calloc(nelem, size)) == NULL)	{	    fprintf(stderr, "Error:  Unable to calloc memory.  Aborting.\n");	    exit(1);	}    return (ret);}void *my_malloc(size_t size){    void *ret;    if((ret = malloc(size)) == NULL)	{	    fprintf(stderr, "Error:  Unable to malloc memory.  Aborting.\n");	    abort();	    exit(1);	}    return (ret);}void *my_realloc(void *ptr,	   size_t size){    void *ret;    if(size <= 0)	{	    printf("reallocating of size <= 0.\n");	}    ret = realloc(ptr, size);    if(NULL == ret)	{	    printf(ERRTAG "Unable to realloc memory. Aborting. "		   "ptr=%p, Size=%d.\n", ptr, size);	    if(ptr == NULL)		{		    printf(ERRTAG "my_realloc: ptr == NULL. Aborting.\n");		}	    exit(1);	}    return (ret);}void *my_chunk_malloc(size_t size,		struct s_linked_vptr **chunk_ptr_head,		int *mem_avail_ptr,		char **next_mem_loc_ptr){/* This routine should be used for allocating fairly small data             * * structures where memory-efficiency is crucial.  This routine allocates   * * large "chunks" of data, and parcels them out as requested.  Whenever     * * it mallocs a new chunk it adds it to the linked list pointed to by       * * chunk_ptr_head.  This list can be used to free the chunked memory.       * * If chunk_ptr_head is NULL, no list of chunked memory blocks will be kept * * -- this is useful for data structures that you never intend to free as   * * it means you don't have to keep track of the linked lists.               * * Information about the currently open "chunk" must be stored by the       * * user program.  mem_avail_ptr points to an int storing how many bytes are * * left in the current chunk, while next_mem_loc_ptr is the address of a    * * pointer to the next free bytes in the chunk.  To start a new chunk,      * * simply set *mem_avail_ptr = 0.  Each independent set of data structures  * * should use a new chunk.                                                  *//* To make sure the memory passed back is properly aligned, I must * * only send back chunks in multiples of the worst-case alignment  * * restriction of the machine.  On most machines this should be    * * a long, but on 64-bit machines it might be a long long or a     * * double.  Change the typedef below if this is the case.          */    typedef long Align;#define CHUNK_SIZE 32768#define FRAGMENT_THRESHOLD 100    char *tmp_ptr;    int aligned_size;    assert(*mem_avail_ptr >= 0);    if((size_t) (*mem_avail_ptr) < size)	{			/* Need to malloc more memory. */	    if(size > CHUNK_SIZE)		{		/* Too big, use standard routine. */		    tmp_ptr = my_malloc(size);/* When debugging, uncomment the code below to see if memory allocation size *//* makes sense *//*#ifdef DEBUG       printf("NB:  my_chunk_malloc got a request for %d bytes.\n",          size);       printf("You should consider using my_malloc for such big requests.\n");#endif */		    if(chunk_ptr_head != NULL)			*chunk_ptr_head =			    insert_in_vptr_list(*chunk_ptr_head, tmp_ptr);		    return (tmp_ptr);		}	    if(*mem_avail_ptr < FRAGMENT_THRESHOLD)		{		/* Only a small scrap left. */		    *next_mem_loc_ptr = my_malloc(CHUNK_SIZE);		    *mem_avail_ptr = CHUNK_SIZE;		    if(chunk_ptr_head != NULL)			*chunk_ptr_head = insert_in_vptr_list(*chunk_ptr_head,							      *next_mem_loc_ptr);		}/* Execute else clause only when the chunk we want is pretty big,  * * and would leave too big an unused fragment.  Then we use malloc * * to allocate normally.                                           */	    else		{		    tmp_ptr = my_malloc(size);		    if(chunk_ptr_head != NULL)			*chunk_ptr_head =			    insert_in_vptr_list(*chunk_ptr_head, tmp_ptr);		    return (tmp_ptr);		}	}/* Find the smallest distance to advance the memory pointer and keep * * everything aligned.                                               */    if(size % sizeof(Align) == 0)	{	    aligned_size = size;	}    else	{	    aligned_size = size + sizeof(Align) - size % sizeof(Align);	}    tmp_ptr = *next_mem_loc_ptr;    *next_mem_loc_ptr += aligned_size;    *mem_avail_ptr -= aligned_size;    return (tmp_ptr);}voidfree_chunk_memory(struct s_linked_vptr *chunk_ptr_head){/* Frees the memory allocated by a sequence of calls to my_chunk_malloc. */    struct s_linked_vptr *curr_ptr, *prev_ptr;    curr_ptr = chunk_ptr_head;    while(curr_ptr != NULL)	{	    free(curr_ptr->data_vptr);	/* Free memory "chunk". */	    prev_ptr = curr_ptr;	    curr_ptr = curr_ptr->next;	    free(prev_ptr);	/* Free memory used to track "chunk". */	}}struct s_linked_vptr *insert_in_vptr_list(struct s_linked_vptr *head,		    void *vptr_to_add){/* Inserts a new element at the head of a linked list of void pointers. * * Returns the new head of the list.                                    */    struct s_linked_vptr *linked_vptr;    linked_vptr = (struct s_linked_vptr *)my_malloc(sizeof(struct							   s_linked_vptr));    linked_vptr->data_vptr = vptr_to_add;    linked_vptr->next = head;    return (linked_vptr);	/* New head of the list */}t_linked_int *insert_in_int_list(t_linked_int * head,		   int data,		   t_linked_int ** free_list_head_ptr){/* Inserts a new element at the head of a linked list of integers.  Returns  * * the new head of the list.  One argument is the address of the head of     * * a list of free ilist elements.  If there are any elements on this free    * * list, the new element is taken from it.  Otherwise a new one is malloced. */    t_linked_int *linked_int;    if(*free_list_head_ptr != NULL)	{	    linked_int = *free_list_head_ptr;	    *free_list_head_ptr = linked_int->next;	}    else	{	    linked_int = (t_linked_int *) my_malloc(sizeof(t_linked_int));	}    linked_int->data = data;    linked_int->next = head;    return (linked_int);}voidfree_int_list(t_linked_int ** int_list_head_ptr){/* This routine truly frees (calls free) all the integer list elements    *  * on the linked list pointed to by *head, and sets head = NULL.          */    t_linked_int *linked_int, *next_linked_int;    linked_int = *int_list_head_ptr;    while(linked_int != NULL)	{	    next_linked_int = linked_int->next;	    free(linked_int);	    linked_int = next_linked_int;	}    *int_list_head_ptr = NULL;}voidalloc_ivector_and_copy_int_list(t_linked_int ** list_head_ptr,				int num_items,				struct s_ivec *ivec,				t_linked_int ** free_list_head_ptr){/* Allocates an integer vector with num_items elements and copies the       * * integers from the list pointed to by list_head (of which there must be   * * num_items) over to it.  The int_list is then put on the free list, and   * * the list_head_ptr is set to NULL.                                        */    t_linked_int *linked_int, *list_head;    int i, *list;    list_head = *list_head_ptr;    if(num_items == 0)	{			/* Empty list. */	    ivec->nelem = 0;	    ivec->list = NULL;	    if(list_head != NULL)		{		    printf(ERRTAG			   "alloc_ivector_and_copy_int_list: Copied %d elements, "			   "but list at %p contains more.\n", num_items,			   (void *)list_head);		    exit(1);		}	    return;	}    ivec->nelem = num_items;    list = (int *)my_malloc(num_items * sizeof(int));    ivec->list = list;    linked_int = list_head;    for(i = 0; i < num_items - 1; i++)	{	    list[i] = linked_int->data;	    linked_int = linked_int->next;	}    list[num_items - 1] = linked_int->data;    if(linked_int->next != NULL)	{	    printf		("Error in alloc_ivector_and_copy_int_list:\n Copied %d elements, "		 "but list at %p contains more.\n", num_items,		 (void *)list_head);	    exit(1);	}    linked_int->next = *free_list_head_ptr;    *free_list_head_ptr = list_head;    *list_head_ptr = NULL;}static int cont;		/* line continued? */char *my_fgets(char *buf,	 int max_size,	 FILE * fp){    /* Get an input line, update the line number and cut off *     * any comment part.  A \ at the end of a line with no   *     * comment part (#) means continue.                      */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -