Added SILC Thread Queue API
[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.  Frames are allocated from the
31    stack itself. */
32 #define SILC_STACK_DEFAULT_NUM 32
33
34 /* Default alignment */
35 #define SILC_STACK_DEFAULT_ALIGN SILC_ALIGNMENT
36
37 /* Maximum allocation that can be made with SilcStack. */
38 #define SILC_STACK_BLOCK_NUM 21
39 #define SILC_STACK_MAX_ALLOC \
40   (SILC_STACK_DEFAULT_SIZE * (1L << (SILC_STACK_BLOCK_NUM - 1)) << 1)
41
42 /* Stack frame data area */
43 typedef struct SilcStackDataStruct {
44   SilcUInt32 bytes_left;                      /* Free bytes in stack */
45   /* Stack data area starts here */
46 } *SilcStackData;
47
48 /* Stack data entry */
49 typedef struct SilcStackDataEntryStruct {
50   struct SilcStackDataEntryStruct *next;
51   SilcStackData data[SILC_STACK_BLOCK_NUM];   /* Blocks */
52   SilcUInt32 bsize;                           /* Default block size */
53   SilcUInt32 si;                              /* Default block index */
54 } *SilcStackDataEntry;
55
56 /* Stack frame */
57 struct SilcStackFrameStruct {
58   struct SilcStackFrameStruct *prev;          /* Pointer to previous frame */
59   SilcUInt32 bytes_used;                      /* Bytes used when pushed */
60   unsigned int sp : 27;                       /* Stack pointer */
61   unsigned int si : 5;                        /* Stack index */
62 };
63
64 /* Align the requested amount bytes.  The `align' defines the requested
65    alignment. */
66 #define SILC_STACK_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1))
67
68 /* Computes the size of stack block si. */
69 #define SILC_STACK_BLOCK_SIZE(stack, si)                \
70   (((si) == 0) ? stack->stack_size :                    \
71    SILC_STACK_DEFAULT_SIZE * (1L << ((si) - 1)) << 1)
72
73 /* Returns a pointer to the data in the given stack block */
74 #define SILC_STACK_DATA_EXT(data, si, bsize, alignment)                 \
75   (((unsigned char *)(data)[si]) +                                      \
76    SILC_STACK_ALIGN(sizeof(**(data)), alignment) +                      \
77    ((bsize) - (data)[si]->bytes_left))
78
79 /* Returns a pointer to the data in the frame */
80 #define SILC_STACK_DATA(stack, si, bsize)                               \
81   SILC_STACK_DATA_EXT((stack)->stack->data, si, bsize, (stack)->alignment)
82
83 #ifdef SILC_DIST_INPLACE
84 /* Statistics updating */
85 #define SILC_STACK_STAT(stack, stat, val) ((stack)->s ## stat += (val))
86 #define SILC_ST_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
87 #else /* !SILC_DIST_INPLACE */
88 #define SILC_STACK_STAT(stack, stat, val)
89 #define SILC_ST_DEBUG(fmt)
90
91 /* Prints statistics of the usage of SilcStack to stdout. */
92 void silc_stack_stats(SilcStack stack);
93 #endif /* SILC_DIST_INPLACE */
94
95 #endif /* SILCSTACK_I_H */