5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2003 - 2005 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
24 #error "Do not include this header directly"
27 /* The default stack size when stack is created */
28 #define SILC_STACK_DEFAULT_SIZE 1024
30 /* Number of pre-allocated stack frames */
31 #define SILC_STACK_DEFAULT_NUM 8
33 /* Default alignment */
34 #define SILC_STACK_DEFAULT_ALIGN sizeof(unsigned long)
36 /* Maximum allocation that can be made with SilcStack. This is
37 SILC_STACK_DEFAULT_SIZE * (2 ^ (SILC_STACK_BLOCK_NUM - 1)). */
38 #define SILC_STACK_MAX_ALLOC 0x02000000
39 #define SILC_STACK_BLOCK_NUM 16
41 /* Stack frame data area */
42 typedef struct SilcStackDataStruct {
43 SilcUInt32 bytes_left; /* Free bytes in stack */
44 /* Stack data area starts here */
48 struct SilcStackFrameStruct {
49 struct SilcStackFrameStruct *prev; /* Pointer to previous frame */
50 SilcUInt32 bytes_used; /* Bytes used when pushed */
51 unsigned int sp : 27; /* Stack pointer */
52 unsigned int si : 5; /* Stack index */
55 /* The SilcStack context */
56 struct SilcStackStruct {
57 SilcStackData stack[SILC_STACK_BLOCK_NUM]; /* Allocated stack blocks */
58 SilcStackFrame *frames; /* Allocated stack frames */
59 SilcStackFrame *frame; /* Current stack frame */
60 SilcUInt32 stack_size; /* Default stack size */
61 #ifdef SILC_DIST_INPLACE
63 SilcUInt32 snum_malloc;
64 SilcUInt32 sbytes_malloc;
65 SilcUInt32 snum_errors;
66 #endif /* SILC_DIST_INPLACE */
69 /* Align the requested amount bytes. The `align' defines the requested
71 #define SILC_STACK_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1))
73 /* Computes the size of stack block si. */
74 #define SILC_STACK_BLOCK_SIZE(stack, si) \
75 (((si) == 0) ? stack->stack_size : \
76 SILC_STACK_DEFAULT_SIZE * (1L << ((si) - 1)) << 1);
78 /* Returns a pointer to the data in the frame */
79 #define SILC_STACK_DATA(stack, si, bsize) \
80 (((unsigned char *)(stack)->stack[si]) + \
81 SILC_STACK_ALIGN(sizeof(**(stack)->stack), SILC_STACK_DEFAULT_ALIGN) + \
82 ((bsize) - (stack)->stack[si]->bytes_left))
84 #ifdef SILC_DIST_INPLACE
85 /* Statistics updating */
86 #define SILC_STACK_STAT(stack, stat, val) ((stack)->s ## stat += (val))
87 #define SILC_ST_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
88 #else /* !SILC_DIST_INPLACE */
89 #define SILC_STACK_STAT(stack, stat, val)
90 #define SILC_ST_DEBUG(fmt)
91 #endif /* SILC_DIST_INPLACE */
93 /* Allocate memory. If the `aligned' is FALSE this allocates unaligned
94 memory, otherwise memory is aligned. Returns pointer to the memory
96 void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, SilcBool aligned);
98 /* Attempts to reallocate memory by changing the size of the `ptr' into
99 `size'. This routine works only if the previous allocation to `stack'
100 was `ptr'. If there is another memory allocation between allocating
101 `ptr' and this call this routine will return NULL. NULL is also returned
102 if the `size' does not fit into the current block. If NULL is returned
103 the old memory remains intact. */
104 void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
105 void *ptr, SilcUInt32 size, SilcBool aligned);
107 #ifdef SILC_DIST_INPLACE
108 /* Prints statistics of the usage of SilcStack to stdout. */
109 void silc_stack_stats(SilcStack stack);
110 #endif /* SILC_DIST_INPLACE */
112 #endif /* SILCSTACK_I_H */