src/glpenv05.c
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 06 Dec 2010 13:09:21 +0100
changeset 1 c445c931472f
permissions -rw-r--r--
Import glpk-4.45

- Generated files and doc/notes are removed
alpar@1
     1
/* glpenv05.c (memory allocation) */
alpar@1
     2
alpar@1
     3
/***********************************************************************
alpar@1
     4
*  This code is part of GLPK (GNU Linear Programming Kit).
alpar@1
     5
*
alpar@1
     6
*  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
alpar@1
     7
*  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
alpar@1
     8
*  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
alpar@1
     9
*  E-mail: <mao@gnu.org>.
alpar@1
    10
*
alpar@1
    11
*  GLPK is free software: you can redistribute it and/or modify it
alpar@1
    12
*  under the terms of the GNU General Public License as published by
alpar@1
    13
*  the Free Software Foundation, either version 3 of the License, or
alpar@1
    14
*  (at your option) any later version.
alpar@1
    15
*
alpar@1
    16
*  GLPK is distributed in the hope that it will be useful, but WITHOUT
alpar@1
    17
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
alpar@1
    18
*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
alpar@1
    19
*  License for more details.
alpar@1
    20
*
alpar@1
    21
*  You should have received a copy of the GNU General Public License
alpar@1
    22
*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
alpar@1
    23
***********************************************************************/
alpar@1
    24
alpar@1
    25
#include "glpapi.h"
alpar@1
    26
alpar@1
    27
/* some processors need data to be properly aligned; the macro
alpar@1
    28
   align_datasize enlarges the specified size of a data item to provide
alpar@1
    29
   a proper alignment of immediately following data */
alpar@1
    30
alpar@1
    31
#define align_datasize(size) ((((size) + 15) / 16) * 16)
alpar@1
    32
/* 16 bytes is sufficient in both 32- and 64-bit environments
alpar@1
    33
   (8 bytes is not sufficient in 64-bit environment due to jmp_buf) */
alpar@1
    34
alpar@1
    35
/***********************************************************************
alpar@1
    36
*  NAME
alpar@1
    37
*
alpar@1
    38
*  glp_malloc - allocate memory block
alpar@1
    39
*
alpar@1
    40
*  SYNOPSIS
alpar@1
    41
*
alpar@1
    42
*  void *glp_malloc(int size);
alpar@1
    43
*
alpar@1
    44
*  DESCRIPTION
alpar@1
    45
*
alpar@1
    46
*  The routine glp_malloc allocates a memory block of size bytes long.
alpar@1
    47
*
alpar@1
    48
*  Note that being allocated the memory block contains arbitrary data
alpar@1
    49
*  (not binary zeros).
alpar@1
    50
*
alpar@1
    51
*  RETURNS
alpar@1
    52
*
alpar@1
    53
*  The routine glp_malloc returns a pointer to the allocated block.
alpar@1
    54
*  To free this block the routine glp_free (not free!) must be used. */
alpar@1
    55
alpar@1
    56
void *glp_malloc(int size)
alpar@1
    57
{     ENV *env = get_env_ptr();
alpar@1
    58
      MEM *desc;
alpar@1
    59
      int size_of_desc = align_datasize(sizeof(MEM));
alpar@1
    60
      if (size < 1 || size > INT_MAX - size_of_desc)
alpar@1
    61
         xerror("glp_malloc: size = %d; invalid parameter\n", size);
alpar@1
    62
      size += size_of_desc;
alpar@1
    63
      if (xlcmp(xlset(size),
alpar@1
    64
          xlsub(env->mem_limit, env->mem_total)) > 0)
alpar@1
    65
         xerror("glp_malloc: memory limit exceeded\n");
alpar@1
    66
      if (env->mem_count == INT_MAX)
alpar@1
    67
         xerror("glp_malloc: too many memory blocks allocated\n");
alpar@1
    68
      desc = malloc(size);
alpar@1
    69
      if (desc == NULL)
alpar@1
    70
         xerror("glp_malloc: no memory available\n");
alpar@1
    71
      memset(desc, '?', size);
alpar@1
    72
      desc->flag = MEM_MAGIC;
alpar@1
    73
      desc->size = size;
alpar@1
    74
      desc->prev = NULL;
alpar@1
    75
      desc->next = env->mem_ptr;
alpar@1
    76
      if (desc->next != NULL) desc->next->prev = desc;
alpar@1
    77
      env->mem_ptr = desc;
alpar@1
    78
      env->mem_count++;
alpar@1
    79
      if (env->mem_cpeak < env->mem_count)
alpar@1
    80
         env->mem_cpeak = env->mem_count;
alpar@1
    81
      env->mem_total = xladd(env->mem_total, xlset(size));
alpar@1
    82
      if (xlcmp(env->mem_tpeak, env->mem_total) < 0)
alpar@1
    83
         env->mem_tpeak = env->mem_total;
alpar@1
    84
      return (void *)((char *)desc + size_of_desc);
alpar@1
    85
}
alpar@1
    86
alpar@1
    87
/***********************************************************************
alpar@1
    88
*  NAME
alpar@1
    89
*
alpar@1
    90
*  glp_calloc - allocate memory block
alpar@1
    91
*
alpar@1
    92
*  SYNOPSIS
alpar@1
    93
*
alpar@1
    94
*  void *glp_calloc(int n, int size);
alpar@1
    95
*
alpar@1
    96
*  DESCRIPTION
alpar@1
    97
*
alpar@1
    98
*  The routine glp_calloc allocates a memory block of (n*size) bytes
alpar@1
    99
*  long.
alpar@1
   100
*
alpar@1
   101
*  Note that being allocated the memory block contains arbitrary data
alpar@1
   102
*  (not binary zeros).
alpar@1
   103
*
alpar@1
   104
*  RETURNS
alpar@1
   105
*
alpar@1
   106
*  The routine glp_calloc returns a pointer to the allocated block.
alpar@1
   107
*  To free this block the routine glp_free (not free!) must be used. */
alpar@1
   108
alpar@1
   109
void *glp_calloc(int n, int size)
alpar@1
   110
{     if (n < 1)
alpar@1
   111
         xerror("glp_calloc: n = %d; invalid parameter\n", n);
alpar@1
   112
      if (size < 1)
alpar@1
   113
         xerror("glp_calloc: size = %d; invalid parameter\n", size);
alpar@1
   114
      if (n > INT_MAX / size)
alpar@1
   115
         xerror("glp_calloc: n = %d; size = %d; array too big\n", n,
alpar@1
   116
            size);
alpar@1
   117
      return xmalloc(n * size);
alpar@1
   118
}
alpar@1
   119
alpar@1
   120
/***********************************************************************
alpar@1
   121
*  NAME
alpar@1
   122
*
alpar@1
   123
*  glp_free - free memory block
alpar@1
   124
*
alpar@1
   125
*  SYNOPSIS
alpar@1
   126
*
alpar@1
   127
*  void glp_free(void *ptr);
alpar@1
   128
*
alpar@1
   129
*  DESCRIPTION
alpar@1
   130
*
alpar@1
   131
*  The routine glp_free frees a memory block pointed to by ptr, which
alpar@1
   132
*  was previuosly allocated by the routine glp_malloc or glp_calloc. */
alpar@1
   133
alpar@1
   134
void glp_free(void *ptr)
alpar@1
   135
{     ENV *env = get_env_ptr();
alpar@1
   136
      MEM *desc;
alpar@1
   137
      int size_of_desc = align_datasize(sizeof(MEM));
alpar@1
   138
      if (ptr == NULL)
alpar@1
   139
         xerror("glp_free: ptr = %p; null pointer\n", ptr);
alpar@1
   140
      desc = (void *)((char *)ptr - size_of_desc);
alpar@1
   141
      if (desc->flag != MEM_MAGIC)
alpar@1
   142
         xerror("glp_free: ptr = %p; invalid pointer\n", ptr);
alpar@1
   143
      if (env->mem_count == 0 ||
alpar@1
   144
          xlcmp(env->mem_total, xlset(desc->size)) < 0)
alpar@1
   145
         xerror("glp_free: memory allocation error\n");
alpar@1
   146
      if (desc->prev == NULL)
alpar@1
   147
         env->mem_ptr = desc->next;
alpar@1
   148
      else
alpar@1
   149
         desc->prev->next = desc->next;
alpar@1
   150
      if (desc->next == NULL)
alpar@1
   151
         ;
alpar@1
   152
      else
alpar@1
   153
         desc->next->prev = desc->prev;
alpar@1
   154
      env->mem_count--;
alpar@1
   155
      env->mem_total = xlsub(env->mem_total, xlset(desc->size));
alpar@1
   156
      memset(desc, '?', size_of_desc);
alpar@1
   157
      free(desc);
alpar@1
   158
      return;
alpar@1
   159
}
alpar@1
   160
alpar@1
   161
/***********************************************************************
alpar@1
   162
*  NAME
alpar@1
   163
*
alpar@1
   164
*  glp_mem_limit - set memory usage limit
alpar@1
   165
*
alpar@1
   166
*  SYNOPSIS
alpar@1
   167
*
alpar@1
   168
*  void glp_mem_limit(int limit);
alpar@1
   169
*
alpar@1
   170
*  DESCRIPTION
alpar@1
   171
*
alpar@1
   172
*  The routine glp_mem_limit limits the amount of memory available for
alpar@1
   173
*  dynamic allocation (in GLPK routines) to limit megabytes. */
alpar@1
   174
alpar@1
   175
void glp_mem_limit(int limit)
alpar@1
   176
{     ENV *env = get_env_ptr();
alpar@1
   177
      if (limit < 0)
alpar@1
   178
         xerror("glp_mem_limit: limit = %d; invalid parameter\n",
alpar@1
   179
            limit);
alpar@1
   180
      env->mem_limit = xlmul(xlset(limit), xlset(1 << 20));
alpar@1
   181
      return;
alpar@1
   182
}
alpar@1
   183
alpar@1
   184
/***********************************************************************
alpar@1
   185
*  NAME
alpar@1
   186
*
alpar@1
   187
*  glp_mem_usage - get memory usage information
alpar@1
   188
*
alpar@1
   189
*  SYNOPSIS
alpar@1
   190
*
alpar@1
   191
*  void glp_mem_usage(int *count, int *cpeak, glp_long *total,
alpar@1
   192
*     glp_long *tpeak);
alpar@1
   193
*
alpar@1
   194
*  DESCRIPTION
alpar@1
   195
*
alpar@1
   196
*  The routine glp_mem_usage reports some information about utilization
alpar@1
   197
*  of the memory by GLPK routines. Information is stored to locations
alpar@1
   198
*  specified by corresponding parameters (see below). Any parameter can
alpar@1
   199
*  be specified as NULL, in which case corresponding information is not
alpar@1
   200
*  stored.
alpar@1
   201
*
alpar@1
   202
*  *count is the number of the memory blocks currently allocated by the
alpar@1
   203
*  routines xmalloc and xcalloc (one call to xmalloc or xcalloc results
alpar@1
   204
*  in allocating one memory block).
alpar@1
   205
*
alpar@1
   206
*  *cpeak is the peak value of *count reached since the initialization
alpar@1
   207
*  of the GLPK library environment.
alpar@1
   208
*
alpar@1
   209
*  *total is the total amount, in bytes, of the memory blocks currently
alpar@1
   210
*  allocated by the routines xmalloc and xcalloc.
alpar@1
   211
*
alpar@1
   212
*  *tpeak is the peak value of *total reached since the initialization
alpar@1
   213
*  of the GLPK library envirionment. */
alpar@1
   214
alpar@1
   215
void glp_mem_usage(int *count, int *cpeak, glp_long *total,
alpar@1
   216
      glp_long *tpeak)
alpar@1
   217
{     ENV *env = get_env_ptr();
alpar@1
   218
      if (count != NULL) *count = env->mem_count;
alpar@1
   219
      if (cpeak != NULL) *cpeak = env->mem_cpeak;
alpar@1
   220
      if (total != NULL) *total = env->mem_total;
alpar@1
   221
      if (tpeak != NULL) *tpeak = env->mem_tpeak;
alpar@1
   222
      return;
alpar@1
   223
}
alpar@1
   224
alpar@1
   225
/* eof */