Skip to content

st use function instead of macro #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,8 @@ signal.$(OBJEXT): {$(VPATH)}signal.c $(RUBY_H_INCLUDES) \
$(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h
sprintf.$(OBJEXT): {$(VPATH)}sprintf.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
{$(VPATH)}regex.h {$(VPATH)}vsnprintf.c $(ENCODING_H_INCLUDES)
st.$(OBJEXT): {$(VPATH)}st.c $(RUBY_H_INCLUDES)
st.$(OBJEXT): {$(VPATH)}st.c $(RUBY_H_INCLUDES) {$(VPATH)}pool_alloc.inc.h \
{$(VPATH)}internal.h
strftime.$(OBJEXT): {$(VPATH)}strftime.c $(RUBY_H_INCLUDES) \
{$(VPATH)}timev.h
string.$(OBJEXT): {$(VPATH)}string.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
Expand Down
21 changes: 21 additions & 0 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,15 @@ vm_xmalloc(rb_objspace_t *objspace, size_t size)
return vm_malloc_fixup(objspace, mem, size);
}

static void *
vm_xmalloc_only(rb_objspace_t *objspace, size_t size)
{
void *mem;

TRY_WITH_GC(mem = malloc(size));
return vm_malloc_fixup(objspace, mem, size);
}

static void *
vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
{
Expand Down Expand Up @@ -850,6 +859,18 @@ ruby_xmalloc(size_t size)
return vm_xmalloc(&rb_objspace, size);
}

size_t
ruby_gcprepare(size_t size)
{
return vm_malloc_prepare(&rb_objspace, size);
}

void *
ruby_xmalloc_prepared(size_t size)
{
return vm_xmalloc_only(&rb_objspace, size);
}

static inline size_t
xmalloc2_size(size_t n, size_t size)
{
Expand Down
4 changes: 4 additions & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ void Init_File(void);

/* gc.c */
void Init_heap(void);
#define xgc_prepare ruby_gcprepare
#define xmalloc_prepared ruby_xmalloc_prepared
size_t xgc_prepare(size_t);
void *xmalloc_prepared(size_t);

/* inits.c */
void rb_call_inits(void);
Expand Down
150 changes: 150 additions & 0 deletions pool_alloc.inc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* this is generic pool allocator
* you should define following macroses:
* ITEM_NAME - unique identifier, which allows to hold functions in a namespace
* ITEM_TYPEDEF(name) - passed to typedef to localize item type
* free_entry - desired name of function for free entry
* alloc_entry - defired name of function for allocate entry
*/

#ifndef COMMON_POOL_TYPES
#define COMMON_POOL_TYPES 1

typedef unsigned int pool_free_counter;
typedef unsigned int pool_holder_counter;

typedef struct pool_entry_list pool_entry_list;
typedef struct pool_holder pool_holder;

typedef struct pool_free_pointer {
pool_entry_list *free;
pool_free_counter count;
pool_holder_counter size; /* size of entry in sizeof(void*) items */
pool_holder_counter total; /* size of entry in sizeof(void*) items */
} pool_free_pointer;

struct pool_entry_list {
pool_holder *holder;
pool_entry_list *fore, *back;
};
#define ENTRY(ptr) ((pool_entry_list*)(ptr))
#define ENTRY_DATA_OFFSET offsetof(pool_entry_list, fore)
#define VOID2ENTRY(ptr) ENTRY((char*)(ptr) - ENTRY_DATA_OFFSET)
#define ENTRY2VOID(ptr) ((void*)((char*)(ptr) + ENTRY_DATA_OFFSET))

struct pool_holder {
pool_holder_counter free, total;
pool_holder_counter size;
pool_free_pointer *free_pointer;
void *data[1];
};
#define POOL_DATA_SIZE ((4096 - sizeof(void*) * 3 - offsetof(pool_holder, data))/sizeof(void*))
#define POOL_HOLDER_SIZE (offsetof(pool_holder, data) + pointer->size*pointer->total*sizeof(void*))
#define POOL_ENTRY_SIZE(item_type) (((sizeof(item_type)+ENTRY_DATA_OFFSET-1)/sizeof(void*)+1))
#define POOL_HOLDER_COUNT(item_type) (POOL_DATA_SIZE/POOL_ENTRY_SIZE(item_type))
#define INIT_POOL(item_type) {NULL, 0, POOL_ENTRY_SIZE(item_type), POOL_HOLDER_COUNT(item_type)}

static void
pool_holder_alloc(pool_free_pointer *pointer)
{
pool_holder *holder;
pool_holder_counter i, size, count;
register void **ptr;
#ifdef xgc_prepare
size_t sz = xgc_prepare(POOL_HOLDER_SIZE);
if (pointer->free != NULL) return;
holder = (pool_holder*)xmalloc_prepared(sz);
#else
holder = (pool_holder*)malloc(POOL_HOLDER_SIZE);
#endif
size = pointer->size;
count = pointer->total;
holder->free = count;
holder->total = count;
holder->size = size;
holder->free_pointer = pointer;
ptr = holder->data;
ENTRY(ptr)->back = NULL;
for(i = count - 1; i; i-- ) {
ENTRY(ptr)->holder = holder;
ENTRY(ptr)->fore = ENTRY(ptr + size);
ENTRY(ptr + size)->back = ENTRY(ptr);
ptr += size;
}
ENTRY(ptr)->holder = holder;
ENTRY(ptr)->fore = pointer->free;
pointer->free = ENTRY(holder->data);
pointer->count += count;
}

static void
pool_holder_free(pool_holder *holder)
{
pool_holder_counter i, size;
void **ptr = holder->data;
pool_free_pointer *pointer = holder->free_pointer;
size = holder->size;

for(i = holder->total; i; i--) {
if (ENTRY(ptr)->fore) {
ENTRY(ptr)->fore->back = ENTRY(ptr)->back;
}
if (ENTRY(ptr)->back) {
ENTRY(ptr)->back->fore = ENTRY(ptr)->fore;
} else {
pointer->free = ENTRY(ptr)->fore;
}
ptr += size;
}
pointer->count-= holder->total;
free(holder);
}

static inline void
pool_free_entry(pool_entry_list *entry)
{
pool_holder *holder = entry->holder;
pool_free_pointer *pointer = holder->free_pointer;
entry->fore = pointer->free;
entry->back = NULL;
if (pointer->free) {
pointer->free->back = entry;
}
pointer->free = entry;
pointer->count++;
holder->free++;
if (holder->free == holder->total && pointer->count > holder->total * 16) {
pool_holder_free(entry->holder);
}
}

static inline pool_entry_list *
pool_alloc_entry(pool_free_pointer *pointer)
{
pool_entry_list *result;
if (pointer->free == NULL) {
pool_holder_alloc(pointer);
}
result = pointer->free;
pointer->free = result->fore;
pointer->count--;
result->holder->free--;
return result;
}

static inline void
pool_free(void *p)
{
pool_free_entry(VOID2ENTRY(p));
}

static inline void*
pool_alloc(pool_free_pointer *pointer)
{
return ENTRY2VOID(pool_alloc_entry(pointer));
}

#undef ENTRY
#undef ENTRY2VOID
#undef VOID2ENTRY
#endif
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy