2014-12-04
2014-12-04 19:23:40 by Arne Goedeke <el@laramies.com>
-
d856cf2f99a1a9056b0bc9799c171add2625a28e
(96 lines)
(+38/-58)
[
Show
| Annotate
]
Branch: bill/master_archive_support
Added new block allocator. It dramatically speeds up free, when
allocating many blocks and deallocation happens non linearly.
18:
#include "block_alloc.h"
#include "operators.h"
#include "pike_float.h"
+ #include "block_allocator.h"
#include "port.h"
#include <errno.h>
667:
/* Allocate some fixed string sizes with BLOCK_ALLOC. */
- /* Use the BLOCK_ALLOC() stuff for short strings */
-
- #undef INIT_BLOCK
- #ifdef ATOMIC_SVALUE
- #define INIT_BLOCK(NEW_STR) do { \
- (NEW_STR)->ref_type = T_STRING; \
- (NEW_STR)->refs = 0; \
- add_ref((NEW_STR)); \
- (NEW_STR)->flags = \
- STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \
- } while(0)
- #else /* !ATOMIC_SVALUE */
- #define INIT_BLOCK(NEW_STR) do { \
- (NEW_STR)->refs = 0; \
- add_ref((NEW_STR)); \
- (NEW_STR)->flags = \
- STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \
- } while(0)
- #endif
-
+
#define SHORT_STRING_BLOCK 256
#define SHORT_STRING_THRESHOLD 15 /* % 4 === -1 */
705:
p_wchar2 str[SHORT_STRING_THRESHOLD+1];
};
- BLOCK_ALLOC(short_pike_string0, SHORT_STRING_BLOCK)
- BLOCK_ALLOC(short_pike_string1, SHORT_STRING_BLOCK)
- BLOCK_ALLOC(short_pike_string2, SHORT_STRING_BLOCK)
+ static struct block_allocator string_allocator[] = {
+ BA_INIT(sizeof(struct short_pike_string0), SHORT_STRING_BLOCK),
+ BA_INIT(sizeof(struct short_pike_string1), SHORT_STRING_BLOCK),
+ BA_INIT(sizeof(struct short_pike_string2), SHORT_STRING_BLOCK)
+ };
- #undef INIT_BLOCK
- #define INIT_BLOCK(x)
+ static struct pike_string * alloc_short_pike_string(unsigned int shift) {
+ struct pike_string * s = (struct pike_string *)ba_alloc(string_allocator+shift);
- #define really_free_short_pike_string(s) do { \
- if (!s->size_shift) { \
- really_free_short_pike_string0((struct short_pike_string0 *)s); \
- } else if (s->size_shift == 1) { \
- really_free_short_pike_string1((struct short_pike_string1 *)s); \
- DO_IF_DEBUG( \
- } else if (s->size_shift != 2) { \
- Pike_fatal("Unsupported string shift: %d\n", s->size_shift); \
- ) \
- } else { \
- really_free_short_pike_string2((struct short_pike_string2 *)s); \
- } \
+ #ifdef ATOMIC_SVALUE
+ s->ref_type = T_STRING;
+ #endif
+ s->refs = 0;
+ add_ref(s); /* For DMALLOC */
+ s->flags = STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT;
+ return s;
+ }
+
+ #define really_free_short_pike_string(s) do { \
+ DO_IF_DEBUG( \
+ if (s->size_shift > 2) \
+ Pike_fatal("Unsupported string shift: %d\n", s->size_shift); \
+ ) \
+ ba_free(string_allocator + s->size_shift, s); \
} while(0)
#define free_unlinked_pike_string(s) do { \
746:
verify_shared_strings_tables();
#endif
if (len <= SHORT_STRING_THRESHOLD) {
- t=(struct pike_string *)alloc_short_pike_string0();
+ t=(struct pike_string *)ba_alloc(string_allocator);
+ t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED | STRING_IS_SHORT;
} else {
t=(struct pike_string *)xalloc(len + 1 + sizeof(struct pike_string_hdr));
t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED;
876:
verify_shared_strings_tables();
#endif
if (len <= SHORT_STRING_THRESHOLD) {
- if (!shift) {
- t = (struct pike_string *)alloc_short_pike_string0();
- } else if (shift == 1) {
- t = (struct pike_string *)alloc_short_pike_string1();
+
#ifdef PIKE_DEBUG
- } else if (shift != 2) {
+ if (shift > 2)
Pike_fatal("Unsupported string shift: %d\n", shift);
#endif /* PIKE_DEBUG */
-
+ t=(struct pike_string *)ba_alloc(string_allocator+shift);
+ t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT;
} else {
- t = (struct pike_string *)alloc_short_pike_string2();
- }
- } else {
+
t=(struct pike_string *)xalloc(((len + 1)<<shift) +
sizeof(struct pike_string_hdr));
t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;
1246: Inside #if defined(PIKE_DEBUG)
if(((ptrdiff_t)s->next) & 1)
Pike_fatal("Freeing shared string again, memory corrupt or other bug!\n");
}
- if ((s->size_shift < 0) || (s->size_shift > 2)) {
+ if (s->size_shift > 2) {
Pike_fatal("Freeing string with bad shift (0x%08x); could it be a type?\n",
s->size_shift);
}
2316:
/*** init/exit memory ***/
void init_shared_string_table(void)
{
- init_short_pike_string0_blocks();
- init_short_pike_string1_blocks();
- init_short_pike_string2_blocks();
+
for(hashprimes_entry=0;hashprimes[hashprimes_entry]<BEGIN_HASH_SIZE;hashprimes_entry++);
SET_HSIZE(hashprimes_entry);
base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size);
2394:
num_strings=0;
#ifdef DO_PIKE_CLEANUP
- free_all_short_pike_string0_blocks();
- free_all_short_pike_string1_blocks();
- free_all_short_pike_string2_blocks();
+ ba_destroy(string_allocator+0);
+ ba_destroy(string_allocator+1);
+ ba_destroy(string_allocator+2);
#endif /* DO_PIKE_CLEANUP */
}
2415:
void count_memory_in_short_pike_strings(size_t *num, size_t *size)
{
size_t num_=0, size_=0;
- count_memory_in_short_pike_string0s(num, size);
- count_memory_in_short_pike_string1s(&num_, &size_);
+ ba_count_all(string_allocator, num, size);
+ ba_count_all(string_allocator+1, &num_, &size_);
*num += num_;
*size += size_;
- count_memory_in_short_pike_string2s(&num_, &size_);
+ ba_count_all(string_allocator+2, &num_, &size_);
*num += num_;
*size += size_;
}