Removed unaligned memory allocation. Added getting/setting
[silc.git] / lib / silcutil / silcstack_i.h
1 /*
2
3   silcstack_i.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2003 - 2007 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 #ifndef SILCSTACK_I_H
21 #define SILCSTACK_I_H
22
23 #ifndef SILCSTACK_H
24 #error "Do not include this header directly"
25 #endif
26
27 /* The default stack size when stack is created */
28 #define SILC_STACK_DEFAULT_SIZE       1024
29
30 /* Number of pre-allocated stack frames */
31 #define SILC_STACK_DEFAULT_NUM        8
32
33 /* Default alignment */
34 #define SILC_STACK_DEFAULT_ALIGN      sizeof(unsigned long)
35
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
40
41 /* Stack frame data area */
42 typedef struct SilcStackDataStruct {
43   SilcUInt32 bytes_left;                      /* Free bytes in stack */
44   /* Stack data area starts here */
45 } *SilcStackData;
46
47 /* Stack frame */
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 */
53 };
54
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
63   /* Statistics */
64   SilcUInt32 snum_malloc;
65   SilcUInt32 sbytes_malloc;
66   SilcUInt32 snum_errors;
67 #endif /* SILC_DIST_INPLACE */
68 };
69
70 /* Align the requested amount bytes.  The `align' defines the requested
71    alignment. */
72 #define SILC_STACK_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1))
73
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);
78
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))
84
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)
92
93 /* Prints statistics of the usage of SilcStack to stdout. */
94 void silc_stack_stats(SilcStack stack);
95 #endif /* SILC_DIST_INPLACE */
96
97 #endif /* SILCSTACK_I_H */