#include #include #include #include #include #include #include #include struct cdat* alloc_cdat(void); struct odat* alloc_odat(void); void alloc_vdat(void); struct link* alloc_link(void); struct ref* alloc_ref(void); struct cdat* curr_cdat(void); struct odat* curr_odat(void); struct vdat* curr_vdat(void); struct set* curr_set(void); struct ref* prev_ref(void); struct model* curr_model(void); void inc_posts(void); #define PAGES_PER_CHUNK 16 #define CURR_CDAT (*cdat_stackp) //"type free" chunk stacking struct chunk_stack { void* chunks[MAX_CHUNKS]; void* *csp; //chunk stack pointer void* dsp[MAX_CHUNKS]; //dat stack pointer (per chunk) int chunk_size; //size of a chunk (including its forfeited page) int max_dats; //number of dats per chunk for this stack } ocs, vcs, ccs, rcs, lcs, pcs; //odat, vdat, and cdat, ref, link, post stacks //type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these) #define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks) #define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1]) #define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1])) #define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \ (CURRENT_CHUNK(STACK) + (STACK).chunk_size)) #define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size)) #define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1]) #define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2]) #define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE)) #define INIT_STACK(STACK,TYPE) \ do { \ (STACK).chunk_size = PAGES_PER_CHUNK; \ (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ CSP_PUSH(STACK); \ } while (0) //Stack-specific macros (called directly from code (safety enforcement) #define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat)) #define ODAT_FULL() (DATA_FULL(ocs,struct odat)) #define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat)) #define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat)) #define VDAT_FULL() (DATA_FULL(vcs,struct vdat)) #define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat)) #define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat)) #define CDAT_FULL() (DATA_FULL(ccs, struct cdat)) #define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat)) #define CURRENT_LINK() (CURRENT_DATP(lcs,struct link)) #define LDAT_FULL() (DATA_FULL(lcs, struct link)) #define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link)) #define CURRENT_POST() (CURRENT_DATP(pcs,struct ref)) #define POST_FULL() (DATA_FULL(pcs,struct ref)) #define POST_ALLOC() (ALLOC_DAT(pcs,struct ref)) #define CURRENT_REF() (CURRENT_DATP(rcs,struct ref)) #define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref)) #define REF_FULL() (DATA_FULL(rcs,struct ref)) #define REF_ALLOC() (ALLOC_DAT(rcs,struct ref)) //Metadata #define CURRENT_SET() (CURRENT_CDAT()->set_list[CURRENT_CDAT()->num_sets]) #define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) #define CURR_QUAD (CURR_ODAT->quad_file) long pagesize; int pages_per_chunk = 10; int num_cdats = 0; int curr_max_cdats = PTRS_IN_PAGE; struct cdat* cdat_buf[PTRS_IN_PAGE]; struct cdat* cdat_stack[PTRS_IN_PAGE]; struct cdat** cdat_stackp; int num_odats = 0; int num_vdats = 0; int num_refs = 0; uint64_t ss_ref_id = 0x00FFFFFF; /* system space for ref_ids */ int num_posts = -1; int curr_max_posts = PTRS_IN_PAGE; struct ref* post_buf[PTRS_IN_PAGE]; int num_links = -1; int curr_max_links = PTRS_IN_PAGE; struct link* link_buf[PTRS_IN_PAGE]; /* The initalization function of the IR. */ int ir_init() { /* Init root cdat and stack */ char root[4] = "root"; if( (cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat))) == NULL) { perror("malloc root class failed\n"); return -1; } cdat_buf[num_cdats]->idx = num_cdats; memmove(cdat_buf[num_cdats]->name, root, 4); cdat_stackp = cdat_stack; *cdat_stackp++ = cdat_buf[num_cdats++]; pagesize = sysconf(_SC_PAGESIZE); return 0; } void ir_quit() { int i; for(i = 0; i <= num_odats ; i++) { } for(i = 0; i <= num_cdats; i++) { } for(i = 0; i <= num_vdats; i++) { } for(i = 0; i <= num_refs; i++) { } for(i = 0; i<= num_links; i++) { } for(i = 0; i<= num_posts; i++) { } } //TODO: FREE MEMORY! struct cdat* alloc_cdat() { num_cdats++; if(curr_max_cdats <= num_cdats) { if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL) perror("realloc cdat_buf failed"); curr_max_cdats += PTRS_IN_PAGE; if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also perror("realloc cdat_stack failed"); } if( (CURR_CDAT = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL ) perror("malloc cdat failed"); return CURR_CDAT; } //these should probably be inline struct odat* alloc_odat () { if(ODAT_FULL()) CSP_PUSH(ocs); else ODAT_ALLOC(); return CURRENT_ODAT(); } void alloc_vdat () { num_vdats++; if(VDAT_FULL()) CSP_PUSH(vcs); else VDAT_ALLOC(); } struct link* alloc_link () { num_links++; if(LDAT_FULL()) CSP_PUSH(lcs); else LDAT_ALLOC(); return CURRENT_LINK(); } struct ref* alloc_ref () { num_refs++; if(REF_FULL()) CSP_PUSH(rcs); else REF_ALLOC(); if(num_refs % 16 == 0) { CURRENT_POST() = CURRENT_REF(); inc_posts(); } return CURRENT_REF(); } void inc_posts() { num_posts++; if(POST_FULL()) CSP_PUSH(pcs); else POST_ALLOC(); } struct cdat* curr_cdat () { return CURR_CDAT; } struct odat* curr_odat () { return CURRENT_ODAT(); } struct vdat* curr_vdat () { return CURRENT_VDAT(); } struct set* curr_set () { return &CURRENT_SET(); } struct ref* prev_ref () { return PREVIOUS_REF(); } struct model* curr_model () { return &CURRENT_MODEL(); }