sicstus
) can be created using
% spld --main=prolog -o sicstus
This will create a development system which is dynamically linked and has no pre-linked foreign resources.
% spld --static -D --resources=random -o main -ltk8.0 -ltcl8.0
This will create a statically linked executable called main
which
has the resource random
pre-linked (statically). The linker will
receive -ltk8.0 -ltcl8.0
which will work under UNIX (if Tcl/Tk is
installed correctly) but will probably fail under Windows.
--userhook
option to perform
initializations in development systems before SP_initialize()
is
called. It also demonstrates how to use this mechanism to redefine the
memory manager bottom layer.
/* -------------------------------------------------------------- * userhook.c - an example of how to use SU_initialize() to * define your own memory manager bottom layer. * * The following commands create a sicstus-executable 'msicstus' which * uses malloc() as its own memory manager bottom layer. In addition * these memory hooks print out messages when they are called. * * -------------------------------------------------------------- */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <sicstus/sicstus.h> #ifdef __GLIBC__ #include <malloc.h> /* for mallopt() */ #endif static char* memman_earliest_start; static char* memman_latest_end; static size_t memman_alignment; static int SPCDECL SU_init_mem_hook(size_t alignment, void* earliest_start, void* latest_end, void *cookie) { fprintf(stderr, "Inside SU_init_mem_hook(%ld, 0x%lx, 0x%lx, 0x%lx)\n", (long)alignment, (unsigned long)earliest_start, (unsigned long)latest_end, (unsigned long)cookie); #if __GLIBC__ /* By default glibc malloc will use mmap for large requests. mmap returns addresses outside the constrained range so we try to prevent malloc from using mmap. There is no guarantee that mmap is not used anyway, especially with threads. */ mallopt(M_MMAP_MAX, 0); #endif /* __GLIBC__ */ memman_earliest_start = (char*)earliest_start; memman_latest_end = (char*)latest_end; memman_alignment = alignment; (void)cookie; /* ignored */ return 1; /* success */ } static void SPCDECL SU_deinit_mem_hook(void *cookie) { /* Note: Currently (3.10) the sicstus DS will not call SP_deinitialize on halt/0, thus SU_deinit_mem_hook will never be called. */ fprintf(stderr, "Inside SU_deinit_mem_hook(0x%lx)\n", (unsigned long)cookie); (void)cookie; /* ignored */ } static void * SPCDECL SU_alloc_mem_hook(size_t size, /* in bytes */ size_t *pactualsize, int constrained, void *cookie) { size_t actual_size; char *p; (void)cookie; /* ignored */ /* Ensure there is room for an aligned block regardless of alignment from malloc(). */ actual_size = size+memman_alignment; p = (char*)malloc(actual_size); fprintf(stderr, "Inside SU_alloc_mem_hook(%ld,%s) " "allocated %ldbyte block at 0x%lx\n", (long)size, (constrained ? "constrained" : "unconstrained"), (long)actual_size, (unsigned long)p); if (p!=NULL && constrained) { if (! (memman_earliest_start <= p && p < memman_latest_end && actual_size < (size_t)(memman_latest_end-p))) { /* did not get a suitable block */ fprintf(stderr, "Inside SU_alloc_mem_hook(%ld,constrained)" "ERROR [0x%lx,0x%lx) is not within [0x%lx,0x%lx)\n", (long)size, (unsigned long)p, (unsigned long)(p+actual_size), (unsigned long)memman_earliest_start, (unsigned long)memman_latest_end); free(p); p = NULL; } } if (p) { *pactualsize = actual_size; return p; } else { fprintf(stderr, "Inside SU_alloc_mem_hook(%ld,%s) " "ERROR failed to allocate memory\n", (long)size, (constrained ? "constrained" : "unconstrained")); return NULL; } } static int SPCDECL SU_free_mem_hook(void *mem, size_t size, int constrained, int force, void *cookie) { fprintf(stderr, "Inside SU_free_mem_hook(0x%lx, %ld, %s, %s, 0x%lx)\n", (unsigned long)mem, (long)size, (constrained ? "constrained" : "unconstrained"), (force ? "FORCE" : "!FORCE"), (unsigned long)cookie ); /* We ignore all these since free() knows how to free anyway. */ (void)size; (void)constrained; (void)force; (void)cookie; free(mem); return 1; /* could reclaim the memory */ } /* Entry point for initializations to be done before SP_initialize() */ int SPCDECL SU_initialize (int argc, char **argv) { void *cookie = NULL; /* we do not use this */ int hints = 0; /* should be zero */ (void)argc; (void)argv; if (!SP_set_memalloc_hooks(hints, SU_init_mem_hook, SU_deinit_mem_hook, SU_alloc_mem_hook, SU_free_mem_hook, cookie)) { fprintf(stderr, "Inside SU_initialize, " "ERROR from SP_set_memalloc_hooks"); return 1; } return 0; }
Compile userhook.c
like this:
% spld -D --userhook userhook.c -o ./msicstus Created "./msicstus" % ./msicstus spld -D --userhook userhook.c -o msicstus.exe ... Created "msicstus.exe" ./msicstus -i -f Inside(SU_init_mem_hook(8, 0x8, 0x10000000, 0x0) Inside SU_alloc_mem_hook(131088,constrained) allocated 131096byte block at 0x410048 Inside SU_alloc_mem_hook(1572880,unconstrained) allocated 1572888byte block at 0x510020 SICStus 3.10.0beta1 (x86-win32-nt-4): Wed Nov 13 12:35:10 2002 Licensed to SICS | ?-