Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2003 - 2005 Pekka Riikonen
+ Copyright (C) 2003 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#endif
/* The default stack size when stack is created */
-#define SILC_STACK_DEFAULT_SIZE 1024
+#define SILC_STACK_DEFAULT_SIZE 1024
-/* Number of pre-allocated stack frames */
-#define SILC_STACK_DEFAULT_NUM 8
+/* Number of pre-allocated stack frames. Frames are allocated from the
+ stack itself. */
+#define SILC_STACK_DEFAULT_NUM 32
/* Default alignment */
-#define SILC_STACK_DEFAULT_ALIGN sizeof(unsigned long)
+#define SILC_STACK_DEFAULT_ALIGN SILC_ALIGNMENT
-/* Maximum allocation that can be made with SilcStack. This is
- SILC_STACK_DEFAULT_SIZE * (2 ^ (SILC_STACK_BLOCK_NUM - 1)). */
-#define SILC_STACK_MAX_ALLOC 0x02000000
-#define SILC_STACK_BLOCK_NUM 16
+/* Maximum allocation that can be made with SilcStack. */
+#define SILC_STACK_BLOCK_NUM 21
+#define SILC_STACK_MAX_ALLOC \
+ (SILC_STACK_DEFAULT_SIZE * (1L << (SILC_STACK_BLOCK_NUM - 1)) << 1)
/* Stack frame data area */
typedef struct SilcStackDataStruct {
/* Stack data area starts here */
} *SilcStackData;
+/* Stack data entry */
+typedef struct SilcStackDataEntryStruct {
+ struct SilcStackDataEntryStruct *next;
+ SilcStackData data[SILC_STACK_BLOCK_NUM]; /* Blocks */
+ SilcUInt32 bsize; /* Default block size */
+ SilcUInt32 si; /* Default block index */
+} *SilcStackDataEntry;
+
/* Stack frame */
struct SilcStackFrameStruct {
struct SilcStackFrameStruct *prev; /* Pointer to previous frame */
unsigned int si : 5; /* Stack index */
};
-/* The SilcStack context */
-struct SilcStackStruct {
- SilcStackData stack[SILC_STACK_BLOCK_NUM]; /* Allocated stack blocks */
- SilcStackFrame *frames; /* Allocated stack frames */
- SilcStackFrame *frame; /* Current stack frame */
- SilcUInt32 stack_size; /* Default stack size */
-#ifdef SILC_DIST_INPLACE
- /* Statistics */
- SilcUInt32 snum_malloc;
- SilcUInt32 sbytes_malloc;
- SilcUInt32 snum_errors;
-#endif /* SILC_DIST_INPLACE */
-};
-
/* Align the requested amount bytes. The `align' defines the requested
alignment. */
#define SILC_STACK_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1))
/* Computes the size of stack block si. */
#define SILC_STACK_BLOCK_SIZE(stack, si) \
(((si) == 0) ? stack->stack_size : \
- SILC_STACK_DEFAULT_SIZE * (1L << ((si) - 1)) << 1);
+ SILC_STACK_DEFAULT_SIZE * (1L << ((si) - 1)) << 1)
+
+/* Returns a pointer to the data in the given stack block */
+#define SILC_STACK_DATA_EXT(data, si, bsize, alignment) \
+ (((unsigned char *)(data)[si]) + \
+ SILC_STACK_ALIGN(sizeof(**(data)), alignment) + \
+ ((bsize) - (data)[si]->bytes_left))
/* Returns a pointer to the data in the frame */
-#define SILC_STACK_DATA(stack, si, bsize) \
- (((unsigned char *)(stack)->stack[si]) + \
- SILC_STACK_ALIGN(sizeof(**(stack)->stack), SILC_STACK_DEFAULT_ALIGN) + \
- ((bsize) - (stack)->stack[si]->bytes_left))
+#define SILC_STACK_DATA(stack, si, bsize) \
+ SILC_STACK_DATA_EXT((stack)->stack->data, si, bsize, (stack)->alignment)
#ifdef SILC_DIST_INPLACE
/* Statistics updating */
#else /* !SILC_DIST_INPLACE */
#define SILC_STACK_STAT(stack, stat, val)
#define SILC_ST_DEBUG(fmt)
-#endif /* SILC_DIST_INPLACE */
-
-/* Allocate memory. If the `aligned' is FALSE this allocates unaligned
- memory, otherwise memory is aligned. Returns pointer to the memory
- or NULL on error. */
-void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned);
-/* Attempts to reallocate memory by changing the size of the `ptr' into
- `size'. This routine works only if the previous allocation to `stack'
- was `ptr'. If there is another memory allocation between allocating
- `ptr' and this call this routine will return NULL. NULL is also returned
- if the `size' does not fit into the current block. If NULL is returned
- the old memory remains intact. */
-void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
- void *ptr, SilcUInt32 size, bool aligned);
-
-#ifdef SILC_DIST_INPLACE
/* Prints statistics of the usage of SilcStack to stdout. */
void silc_stack_stats(SilcStack stack);
#endif /* SILC_DIST_INPLACE */