X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fpool.c;h=5309c729efa77c2f5ce66cf1e9521a64fc16489d;hb=96ccc18094e24d977bb8285143dc4c69f9caa8b4;hp=dbdd71b6cbbf250fbb91248e6c8cc820da13e4f0;hpb=3bbb4370239deb29ebbf813d258aef6249e2a431;p=pspp diff --git a/src/libpspp/pool.c b/src/libpspp/pool.c index dbdd71b6cb..5309c729ef 100644 --- a/src/libpspp/pool.c +++ b/src/libpspp/pool.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,14 +15,19 @@ along with this program. If not, see . */ #include -#include "pool.h" + +#include "libpspp/pool.h" + #include #include -#include -#include "message.h" -#include "str.h" -#include "xalloc.h" +#include "libpspp/assertion.h" +#include "libpspp/message.h" +#include "libpspp/temp-file.h" +#include "libpspp/str.h" + +#include "gl/xalloc-oversized.h" +#include "gl/xalloc.h" /* Fast, low-overhead memory block suballocator. */ struct pool @@ -45,6 +50,7 @@ enum { POOL_GIZMO_MALLOC, POOL_GIZMO_FILE, + POOL_GIZMO_TEMP_FILE, POOL_GIZMO_SUBPOOL, POOL_GIZMO_REGISTERED, }; @@ -64,7 +70,7 @@ struct pool_gizmo /* Type-dependent info. */ union { - FILE *file; /* POOL_GIZMO_FILE. */ + FILE *file; /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */ struct pool *subpool; /* POOL_GIZMO_SUBPOOL. */ /* POOL_GIZMO_REGISTERED. */ @@ -91,10 +97,16 @@ union align void (*fp) (void); long l; double d; + + /* glibc jmp_buf on ia64 requires 16-byte alignment. This ensures it. */ + size_t s[2]; }; /* This should be the alignment size used by malloc(). The size of - the union above is correct, if not optimal, in all known cases. */ + the union above is correct, if not optimal, in all known cases. + + This is normally 8 bytes for 32-bit architectures and 16 bytes for 64-bit + architectures. */ #define ALIGN_SIZE sizeof (union align) /* DISCRETE_BLOCKS may be declared as nonzero to prevent @@ -294,7 +306,8 @@ pool_alloc (struct pool *pool, size_t amt) void * pool_alloc_unaligned (struct pool *pool, size_t amt) { - assert (pool != NULL); + if (pool == NULL) + return xmalloc (amt); #ifndef DISCRETE_BLOCKS /* Strings need not be aligned on any boundary, but some @@ -755,41 +768,78 @@ pool_fclose (struct pool *pool, FILE *file) return fclose (file); } -/* Creates a temporary file with tmpfile() and returns a handle to it - if successful or a null pointer if not. +/* Attaches FILE to POOL. The file will be closed automatically when POOL is destroyed, or it may be closed explicitly in advance using pool_fclose(), or detached from the pool with pool_detach_file(). */ +void +pool_attach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g = pool_alloc (pool, sizeof *g); + g->type = POOL_GIZMO_FILE; + g->p.file = file; + add_gizmo (pool, g); +} + +/* Detaches FILE from POOL. */ +void +pool_detach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g; + + for (g = pool->gizmos; g; g = g->next) + if (g->type == POOL_GIZMO_FILE && g->p.file == file) + { + delete_gizmo (pool, g); + return; + } +} + +/* Creates a temporary file with create_temp_file() and returns a handle to it + if successful or a null pointer if not. + The file will be closed automatically when POOL is destroyed, or it + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ FILE * -pool_tmpfile (struct pool *pool) +pool_create_temp_file (struct pool *pool) { - FILE *file = tmpfile (); + FILE *file = create_temp_file (); if (file != NULL) - pool_attach_file (pool, file); + pool_attach_temp_file (pool, file); return file; } -/* Attaches FILE to POOL. +/* Closes file FILE managed by POOL. + FILE must have been opened with create_temp_file(). */ +void +pool_fclose_temp_file (struct pool *pool, FILE *file) +{ + assert (pool && file); + pool_detach_temp_file (pool, file); + close_temp_file (file); +} + +/* Attaches FILE, which must have been opened with create_temp_file(), to POOL. The file will be closed automatically when POOL is destroyed, or it - may be closed explicitly in advance using pool_fclose(), or - detached from the pool with pool_detach_file(). */ + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ void -pool_attach_file (struct pool *pool, FILE *file) +pool_attach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g = pool_alloc (pool, sizeof *g); - g->type = POOL_GIZMO_FILE; + g->type = POOL_GIZMO_TEMP_FILE; g->p.file = file; add_gizmo (pool, g); } -/* Detaches FILE from POOL. */ +/* Detaches FILE that was opened with create_temp_file() from POOL. */ void -pool_detach_file (struct pool *pool, FILE *file) +pool_detach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g; for (g = pool->gizmos; g; g = g->next) - if (g->type == POOL_GIZMO_FILE && g->p.file == file) + if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file) { delete_gizmo (pool, g); return; @@ -947,6 +997,9 @@ free_gizmo (struct pool_gizmo *gizmo) case POOL_GIZMO_FILE: fclose (gizmo->p.file); /* Ignore errors. */ break; + case POOL_GIZMO_TEMP_FILE: + close_temp_file (gizmo->p.file); /* Ignore errors. */ + break; case POOL_GIZMO_SUBPOOL: gizmo->p.subpool->parent = NULL; pool_destroy (gizmo->p.subpool);