1
/* -*- Mode: C; c-basic-offset: 2; -*- */
2
/* GdkPixbuf library - test loaders
4
* Copyright (C) 2001 S�ren Sandmann (sandmann@daimi.au.dk)
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22
#include "gdk-pixbuf/gdk-pixbuf.h"
28
#define PRETEND_MEM_SIZE (16 * 1024 * 1024)
29
#define REMAINING_MEM_SIZE 100000
32
static int current_allocation = 0;
33
static int max_allocation = 0;
35
#define HEADER_SPACE sizeof(void*)
38
record_bytes (gpointer mem, gsize bytes)
41
(current_allocation + bytes) > max_allocation)
49
*(void **)mem = GINT_TO_POINTER (bytes);
51
g_assert (GPOINTER_TO_INT (*(void**)mem) == bytes);
53
g_assert (current_allocation >= 0);
54
current_allocation += bytes;
55
g_assert (current_allocation >= 0);
57
g_assert ( mem == (void*) ((((char*)mem) + HEADER_SPACE) - HEADER_SPACE) );
58
return ((char*)mem) + HEADER_SPACE;
62
limited_try_malloc (gsize n_bytes)
64
return record_bytes (malloc (n_bytes + HEADER_SPACE), n_bytes);
68
limited_malloc (gsize n_bytes)
70
return limited_try_malloc (n_bytes);
74
limited_calloc (gsize n_blocks,
77
int bytes = n_blocks * n_block_bytes + HEADER_SPACE;
78
gpointer mem = malloc (bytes);
79
memset (mem, 0, bytes);
80
return record_bytes (mem, n_blocks * n_block_bytes);
84
limited_free (gpointer mem)
86
gpointer real = ((char*)mem) - HEADER_SPACE;
88
g_assert (current_allocation >= 0);
89
current_allocation -= GPOINTER_TO_INT (*(void**)real);
90
g_assert (current_allocation >= 0);
96
limited_try_realloc (gpointer mem,
101
return limited_try_malloc (n_bytes);
109
real = ((char*)mem) - HEADER_SPACE;
111
g_assert (current_allocation >= 0);
112
current_allocation -= GPOINTER_TO_INT (*(void**)real);
113
g_assert (current_allocation >= 0);
115
return record_bytes (realloc (real, n_bytes + HEADER_SPACE), n_bytes);
120
limited_realloc (gpointer mem,
123
return limited_try_realloc (mem, n_bytes);
126
static GMemVTable limited_table = {
136
mem_test (const gchar *bytes, gsize len)
138
gboolean did_fail = FALSE;
140
GdkPixbufLoader *loader;
141
GList *loaders = NULL;
145
loader = gdk_pixbuf_loader_new ();
146
gdk_pixbuf_loader_write (loader, (guchar *) bytes, len, &err);
153
gdk_pixbuf_loader_close (loader, NULL);
160
loaders = g_list_prepend (loaders, loader);
163
for (i = loaders; i != NULL; i = i->next)
164
g_object_unref (i->data);
165
g_list_free (loaders);
169
almost_exhaust_memory (void)
171
gpointer x = g_malloc (REMAINING_MEM_SIZE);
172
while (g_try_malloc (REMAINING_MEM_SIZE / 10))
180
g_print ("usage: pixbuf-lowmem <pretend_memory_size> <files>\n");
185
main (int argc, char **argv)
193
max_allocation = strtol (argv[1], &endptr, 10);
194
if (endptr == argv[1])
197
/* Set a malloc which emulates low mem */
198
g_mem_set_vtable (&limited_table);
201
g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
205
/* How do the loaders behave when memory is low?
206
It depends on the state the above tests left the
209
- Sometimes the png loader tries to report an
210
"out of memory", but then g_strdup_printf() calls
211
g_malloc(), which fails.
213
- There are unchecked realloc()s inside libtiff, which means it
214
will never work with low memory, unless something drastic is
215
done, like allocating a lot of memory upfront and release it
216
before entering libtiff. Also, some TIFFReadRGBAImage calls
217
returns successfully, even though they have called the error
218
handler with an 'out of memory' message.
221
almost_exhaust_memory ();
223
g_print ("Allocated %dK of %dK, %dK free during tests\n",
224
current_allocation / 1024, max_allocation / 1024,
225
(max_allocation - current_allocation) / 1024);
227
for (i = 2; i < argc; ++i)
233
if (!g_file_get_contents (argv[i], &contents, &size, &err))
235
g_print ("couldn't read %s: %s\n", argv[i], err->message);
240
g_print ("%-40s memory ", argv[i]);
242
mem_test (contents, size);
243
g_print ("\tpassed\n");