Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / memory.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/*
9af1c6c4 dan1998-10-21 14:43:47 +00002 * Window Maker miscelaneous function library
6830b057 dan2004-10-12 21:28:27 +00003 *
4153e2fd dan2003-01-16 23:30:45 +00004 * Copyright (c) 1997-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00005 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00006 * 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.
10 *
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.
15 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
558615a8 dan2004-10-30 05:46:37 +000021#include "wconfig.h"
9d2e6ef9 scottc1998-09-29 22:36:29 +000022#include "WUtil.h"
23
24#include <stdlib.h>
25#include <sys/types.h>
26#include <unistd.h>
27#include <stdio.h>
28#include <string.h>
29#include <assert.h>
416e3a82 dan1999-01-25 19:06:50 +000030#include <signal.h>
9d2e6ef9 scottc1998-09-29 22:36:29 +000031
80fb09a7 kojima1999-10-09 20:07:23 +000032#ifdef TEST_WITH_GC
33#include <gc/gc.h>
34#endif
35
9d2e6ef9 scottc1998-09-29 22:36:29 +000036#ifndef False
37# define False 0
38#endif
39#ifndef True
40# define True 1
41#endif
42
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020043static void defaultHandler(int bla)
416e3a82 dan1999-01-25 19:06:50 +000044{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020045 if (bla)
46 kill(getpid(), SIGABRT);
47 else
48 exit(1);
416e3a82 dan1999-01-25 19:06:50 +000049}
50
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020051static waborthandler *aborthandler = (waborthandler *) defaultHandler;
416e3a82 dan1999-01-25 19:06:50 +000052
53#define wAbort(a) (*aborthandler)(a)
54
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020055waborthandler *wsetabort(waborthandler * handler)
416e3a82 dan1999-01-25 19:06:50 +000056{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020057 waborthandler *old = aborthandler;
416e3a82 dan1999-01-25 19:06:50 +000058
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020059 aborthandler = handler;
416e3a82 dan1999-01-25 19:06:50 +000060
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020061 return old;
416e3a82 dan1999-01-25 19:06:50 +000062}
63
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020064static int Aborting = 0; /* if we're in the middle of an emergency exit */
9d2e6ef9 scottc1998-09-29 22:36:29 +000065
66static WMHashTable *table = NULL;
67
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020068void *wmalloc(size_t size)
9d2e6ef9 scottc1998-09-29 22:36:29 +000069{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020070 void *tmp;
80fb09a7 kojima1999-10-09 20:07:23 +000071
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020072 assert(size > 0);
edc57cf7 kojima2000-09-25 19:21:45 +000073
80fb09a7 kojima1999-10-09 20:07:23 +000074#ifdef TEST_WITH_GC
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020075 tmp = GC_malloc(size);
80fb09a7 kojima1999-10-09 20:07:23 +000076#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020077 tmp = malloc(size);
80fb09a7 kojima1999-10-09 20:07:23 +000078#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020079 if (tmp == NULL) {
80 wwarning("malloc() failed. Retrying after 2s.");
81 sleep(2);
ef42fce3 dan1999-12-01 22:25:48 +000082#ifdef TEST_WITH_GC
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020083 tmp = GC_malloc(size);
ef42fce3 dan1999-12-01 22:25:48 +000084#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020085 tmp = malloc(size);
ef42fce3 dan1999-12-01 22:25:48 +000086#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020087 if (tmp == NULL) {
88 if (Aborting) {
89 fputs("Really Bad Error: recursive malloc() failure.", stderr);
90 exit(-1);
91 } else {
92 wfatal("virtual memory exhausted");
93 Aborting = 1;
94 wAbort(False);
95 }
96 }
97 }
98 return tmp;
9d2e6ef9 scottc1998-09-29 22:36:29 +000099}
100
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200101void *wmalloc0(size_t size)
3301b57d kojima2005-03-11 01:56:06 +0000102{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200103 void *ptr = wmalloc(size);
104 if (!ptr)
105 return NULL;
3301b57d kojima2005-03-11 01:56:06 +0000106
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200107 memset(ptr, 0, size);
3301b57d kojima2005-03-11 01:56:06 +0000108
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200109 return ptr;
3301b57d kojima2005-03-11 01:56:06 +0000110}
111
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200112void *wrealloc(void *ptr, size_t newsize)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000113{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200114 void *nptr;
115
116 if (!ptr) {
117 nptr = wmalloc(newsize);
118 } else if (newsize == 0) {
119 wfree(ptr);
120 nptr = NULL;
121 } else {
80fb09a7 kojima1999-10-09 20:07:23 +0000122#ifdef TEST_WITH_GC
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200123 nptr = GC_realloc(ptr, newsize);
80fb09a7 kojima1999-10-09 20:07:23 +0000124#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200125 nptr = realloc(ptr, newsize);
80fb09a7 kojima1999-10-09 20:07:23 +0000126#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200127 if (nptr == NULL) {
128 wwarning("realloc() failed. Retrying after 2s.");
129 sleep(2);
80fb09a7 kojima1999-10-09 20:07:23 +0000130#ifdef TEST_WITH_GC
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200131 nptr = GC_realloc(ptr, newsize);
80fb09a7 kojima1999-10-09 20:07:23 +0000132#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200133 nptr = realloc(ptr, newsize);
80fb09a7 kojima1999-10-09 20:07:23 +0000134#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200135 if (nptr == NULL) {
136 if (Aborting) {
137 fputs("Really Bad Error: recursive realloc() failure.", stderr);
138 exit(-1);
139 } else {
140 wfatal("virtual memory exhausted");
141 Aborting = 1;
142 wAbort(False);
143 }
144 }
145 }
146 }
147 return nptr;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000148}
149
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200150void *wretain(void *ptr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000151{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200152 int *refcount;
6830b057 dan2004-10-12 21:28:27 +0000153
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200154 if (!table) {
155 table = WMCreateHashTable(WMIntHashCallbacks);
156 }
6830b057 dan2004-10-12 21:28:27 +0000157
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200158 refcount = WMHashGet(table, ptr);
159 if (!refcount) {
160 refcount = wmalloc(sizeof(int));
161 *refcount = 1;
162 WMHashInsert(table, ptr, refcount);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000163#ifdef VERBOSE
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200164 printf("== %i (%p)\n", *refcount, ptr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000165#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200166 } else {
167 (*refcount)++;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000168#ifdef VERBOSE
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200169 printf("+ %i (%p)\n", *refcount, ptr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000170#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200171 }
6830b057 dan2004-10-12 21:28:27 +0000172
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200173 return ptr;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000174}
175
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200176void wfree(void *ptr)
80fb09a7 kojima1999-10-09 20:07:23 +0000177{
178#ifdef TEST_WITH_GC
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200179 GC_free(ptr);
80fb09a7 kojima1999-10-09 20:07:23 +0000180#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200181 free(ptr);
80fb09a7 kojima1999-10-09 20:07:23 +0000182#endif
183}
184
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200185void wrelease(void *ptr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000186{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200187 int *refcount;
188
189 refcount = WMHashGet(table, ptr);
190 if (!refcount) {
191 wwarning("trying to release unexisting data %p", ptr);
192 } else {
193 (*refcount)--;
194 if (*refcount < 1) {
9d2e6ef9 scottc1998-09-29 22:36:29 +0000195#ifdef VERBOSE
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200196 printf("RELEASING %p\n", ptr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000197#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200198 WMHashRemove(table, ptr);
199 wfree(refcount);
200 wfree(ptr);
201 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000202#ifdef VERBOSE
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200203 else {
204 printf("- %i (%p)\n", *refcount, ptr);
205 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000206#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200207 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000208}