5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2003 - 2007 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 SilcUInt32 alignment; /* Memory alignment */
62 #ifdef SILC_DIST_INPLACE
64 SilcUInt32 snum_malloc;
65 SilcUInt32 sbytes_malloc;
66 SilcUInt32 snum_errors;
67 #endif /* SILC_DIST_INPLACE */
70 /* Align the requested amount bytes. The `align' defines the requested
72 #define SILC_STACK_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1))
74 /* Computes the size of stack block si. */
75 #define SILC_STACK_BLOCK_SIZE(stack, si) \
76 (((si) == 0) ? stack->stack_size : \
77 SILC_STACK_DEFAULT_SIZE * (1L << ((si) - 1)) << 1);
79 /* Returns a pointer to the data in the frame */
80 #define SILC_STACK_DATA(stack, si, bsize) \
81 (((unsigned char *)(stack)->stack[si]) + \
82 SILC_STACK_ALIGN(sizeof(**(stack)->stack), (stack)->alignment) + \
83 ((bsize) - (stack)->stack[si]->bytes_left))
85 #ifdef SILC_DIST_INPLACE
86 /* Statistics updating */
87 #define SILC_STACK_STAT(stack, stat, val) ((stack)->s ## stat += (val))
88 #define SILC_ST_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
89 #else /* !SILC_DIST_INPLACE */
90 #define SILC_STACK_STAT(stack, stat, val)
91 #define SILC_ST_DEBUG(fmt)
93 /* Prints statistics of the usage of SilcStack to stdout. */
94 void silc_stack_stats(SilcStack stack);
95 #endif /* SILC_DIST_INPLACE */
97 #endif /* SILCSTACK_I_H */