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

📄 az_util.c

📁 并行解法器,功能强大
💻 C
📖 第 1 页 / 共 5 页
字号:
                          (int *) NULL);}/******************************************************************************//******************************************************************************//******************************************************************************/double *AZ_manage_memory(unsigned int input_size, int action, int type,                          char *name, int *status)/*******************************************************************************  AZ_manage_memory() either frees memory that was previously allocated or  returns a pointer to memory for future use (this pointer can be a newly  allocated block or a block that was previously allocated).  Author:          Ray S. Tuminaro, SNL, 1422  =======  Return code:     double *,  pointer to allocated memory.  ============  Parameter list:  ===============  input_size:      integer variable. On input, size indicates the amount of                   memory that is needed (NOTE: ignored if action == AZ_CLEAR).  action:          On input, action indicates whether to allocate or free                   memory.                   = AZ_ALLOC: look for a chunk of memory (in the memory                               management list pointed to by 'head') that has                               already been allocated with a memory-type 'type',                               a size in bytes of 'size', and labelled with the                               string 'name'.                               If this memory is found return a pointer to this                               memory and set *status to AZ_OLD_ADDRESS.                               If this memory is not found allocate the memory,                               put it in the memory management list, return a                               pointer to this piece of memory, and set *status                               to AZ_NEW_ADDRESS.                   = AZ_REALLOC:look for a chunk of memory (in the memory                               management list pointed to by 'head') that has                               already been allocated with a memory-type 'type',                               and labelled with the string 'name'. Reallocate                               this item with size 'size' and change the size                               field.                   = AZ_CLEAR: free all memory associated with any chunk of                               memory that has the memory-type 'type'.                   = AZ_SELECTIVE_CLEAR: free all memory associated with any                               chunk ofmemory that has the memory-type 'type'                               and the memory-name 'name'.  type:            On input, a number associated with each piece of memory that                   is allocated.  This number is used when checking to see if                   a requested piece of memory is already allocated. This number                   is also used when freeing up memory (see AZ_CLEAR).                   NOTE: Aztec uses the type AZ_SYS for temporary internal                         pieces of memory that can be deallocated after solving                         a linear system.  name:            On input, a character string associated with each piece of                   memory that is allocated. This string is used when checking                   to see if a requested piece of memory is already allocated.                   Additionally, this string is printed when AZ_manage_memory()                   fails to allocate memory.  status:          On output,                   *status = AZ_NEW_ADDRESS indicates that a new piece of memory                                            has been allocated.                   *status = AZ_OLD_ADDRESS indicates that a pointer to a                                            previously allocated chunk of memory                                            is returned.                   NOTE: status is not used if action == AZ_CLEAR has been                         allocated.*******************************************************************************/{  /* local variables */  struct mem_ptr {    char   *name;    double *address;    int     type;    int     size;    char    special;    struct mem_ptr *next;  };  long int size;  static struct mem_ptr *head = NULL;  struct mem_ptr        *current, *temp,*prev, *thenext;  int                   found = 0, i,j, n2, nn;int aligned_str_mem,aligned_j,aligned_size;double *dtmp;  /**************************** execution begins ******************************/  size = (int) input_size;  current = head;  if (action == -43) {    /* print the list */    while (current != NULL) {      (void) printf("(%8d,%8d  %ld) ==> %s\n", current->type, current->size,                      (long int) current->address, current->name);      prev    = current;      current = current->next;    }    return (double *) 0;  }  else if (action == AZ_ALLOC) {    if (size == 0) return (double *) 0;    /* first look for entry */    while ( current != NULL) {      if ( (current->size == size) && (current->type == type) &&           (strcmp(current->name,name) == 0) ) {        found = 1;        break;      }      prev    = current;      current = current->next;    }    if (found == 0) {      /*       * Put in a new entry if it has the type 0 we will put it at the front of       * the list else put it at the end of the list This is done for efficiency       * reasons as type = 0 is used a lot.       */      j = strlen(name) + 1;      aligned_str_mem = sizeof(struct mem_ptr);      aligned_j       = j;      aligned_size    = size;      aligned_str_mem +=  (sizeof(double) - (aligned_str_mem%sizeof(double)));      aligned_j       +=  (sizeof(double) - (aligned_j%sizeof(double)));      aligned_size    +=  (sizeof(double) - (aligned_size%sizeof(double)));      dtmp = (double *) AZ_allocate((unsigned int) (aligned_str_mem+aligned_j+                                                aligned_size) );      if (dtmp== NULL) {        (void) fprintf(stderr, "Error: Not enough space to allocate\n");        (void) fprintf(stderr, "       '%s' in memory_manage()\n", name);        (void) fprintf(stderr, "        Asked for %ld bytes. Perhaps\n", size);        (void) fprintf(stderr, "        a smaller problem should be run\n");        exit(-1);      }      temp = (struct mem_ptr *) &(dtmp[aligned_size/sizeof(double)]);      temp->name = (char *)     &(dtmp[(aligned_str_mem+aligned_size)/				          sizeof(double)]);      temp->address = dtmp;      for (i = 0 ; i < j; i++ ) (temp->name)[i] = name[i];      temp->special = 'N';      temp->type = type;      temp->size = size;      /* put at the head of the list */      temp->next = head;      head       = temp;      *status = AZ_NEW_ADDRESS;      return temp->address;    }    else {      *status = AZ_OLD_ADDRESS;      return current->address;    }  }  else if (action == AZ_CLEAR) {    prev = NULL;    while (current != NULL) {      if (current->type == type) {        if (prev == NULL) head       = current->next;        else              prev->next = current->next;        temp = current->next;        AZ_free(current->address);        current = temp;      }      else {        prev    = current;        current = current->next;      }    }    return (double *) 0;  }  else if (action == AZ_EVERYBODY_BUT_CLEAR) {    prev = NULL;    while (current != NULL) {      if ( (current->type == type) &&           (strncmp(current->name,name,5) != 0) ) {        if (prev == NULL) head       = current->next;        else              prev->next = current->next;        temp = current->next;        AZ_free(current->address);        current = temp;      }      else {        prev    = current;        current = current->next;      }    }    return (double *) 0;  }  else if (action == AZ_SUBSELECTIVE_CLEAR) {    prev = NULL;    while (current != NULL) {      if ( (current->type == type) &&           (strncmp(current->name,name,5) == 0) ) {        if (prev == NULL) head       = current->next;        else              prev->next = current->next;        temp = current->next;        AZ_free(current->address);        current = temp;      }      else {        prev    = current;        current = current->next;      }    }    return (double *) 0;  }  else if (action == AZ_SELECTIVE_CLEAR) {    prev = NULL;    while (current != NULL) {      if ( (current->type == type) &&         (strcmp(current->name,name) == 0) ) {        if (prev == NULL) head       = current->next;        else              prev->next = current->next;        temp = current->next;        AZ_free(current->address);        current = temp;      }      else {        prev    = current;        current = current->next;      }    }    return (double *) 0;  }  else if ( (action == AZ_REALLOC) || (action == AZ_SPEC_REALLOC)) {     prev = NULL;    /* first look for entry */    while ( current != NULL) {      if ( (current->type == type) &&           (strcmp(current->name,name) == 0) ) {        found = 1;        break;      }      prev    = current;      current = current->next;    }    if (current == NULL) {      (void) fprintf(stderr, "memory_management error: %s with type %d not",                     name, type);      (void) fprintf(stderr, " found during reallocation\n");      exit(-1);    }    if ( (action == AZ_REALLOC) && (current->special != 'N')) {        *status = AZ_SPECIAL;        return(current->address);    }    else if (current->special != 'N') {       *status = AZ_SPECIAL;    }    else *status = AZ_OLD_ADDRESS;    if (current->size == size) return(current->address);    j = strlen(name) + 1;    aligned_str_mem = sizeof(struct mem_ptr);    aligned_j       = j;    aligned_size    = size;    aligned_str_mem +=  (sizeof(double) - (aligned_str_mem%sizeof(double)));    aligned_j       +=  (sizeof(double) - (aligned_j%sizeof(double)));    aligned_size    +=  (sizeof(double) - (aligned_size%sizeof(double)));    thenext = current->next;    dtmp    = current->address;    dtmp    = (double *) AZ_realloc((char *) dtmp,(unsigned int)                                     aligned_str_mem+aligned_j+aligned_size);    if (dtmp == NULL) {      (void) fprintf(stderr, "Error:Not enough memory for '%s'\n", name);      (void) fprintf(stderr, "      Asked for %ld bytes. Perhaps\n", size);      (void) fprintf(stderr, "      a smaller problem should be run\n");      exit(-1);    }    temp = (struct mem_ptr *) &(dtmp[aligned_size/sizeof(double)]);    temp->name = (char *)     &(dtmp[(aligned_str_mem+aligned_size)/                                          sizeof(double)]);    temp->address = dtmp;    for (i = 0 ; i < j; i++ ) (temp->name)[i] = name[i];    temp->special = 'N';    if (action == AZ_SPEC_REALLOC) temp->special = 'S';    temp->type = type;    temp->size = size;    if (prev == NULL) head  = temp;    else  prev->next = temp;    temp->next = thenext;    return temp->address;  }  else if (action == AZ_RESET_STRING) {      prev = NULL;      /* first look for entry */      n2 = strlen(name);     while ( current != NULL) {       nn = strlen(current->name);       if ( (current->type == type) &&            (strncmp(current->name,name,(unsigned) nn) == 0) &&            (n2 < nn*2)) {         found = 1;         break;       }       prev    = current;       current = current->next;     }     if (current == NULL) {       (void) fprintf(stderr, "memory_management error: %s with type %d not",                      name, type);       (void) fprintf(stderr, " found while changing name\n");       exit(-1);     }     sprintf(current->name,"%s",&(name[nn]));     *status = AZ_OLD_ADDRESS;  }  else if (action == AZ_EMPTY ) {     if (current == NULL) *status = -1;     else *status = 1;  }  else if (action == AZ_LOOKFOR_PRINT) {    /* first look for entry */    printf("Looking in system for possible mismatches\n");    while ( current != NULL) {      if (current->name[0] == 'P') {         if (current->type != type) {            printf("AZ_name/type does not match %d %d\n\n", current->type,type);            return(NULL);         }         i = strcmp(current->name,name);         if (i != 0) {            printf("option keys do not match (%s) (%s)\n", current->name,name);                     nn = 1;            while ( (current->name[nn] != ' ' )&&(nn < (int) strlen(current->name))) {               if (current->name[nn] != name[nn]) break;               nn++;            }            if ((current->name[nn] != ' ') || (name[nn] != ' ')) {               sscanf(&(current->name[1]),"%d", &i);               sscanf(&(name[1]),"%d", &j);               printf("found context with different matrix size (%d vs. %d)\n",                      i,j);               return(NULL);            }            i = (int) ( name[++nn] - '!');            j = (int) ( current->name[nn] - '!');            if (j != i) {               printf("==> check overlapping and reordering choices\n");               return(NULL);            }            i = (int) ( name[++nn] - '!');

⌨️ 快捷键说明

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