#include #include #include #include #include #include #include #include struct cdat* alloc_cdat(void); struct odat* alloc_odat(void); struct vdat* 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 variant* curr_variant(void); struct set* curr_set(void); struct ref* curr_ref(void); struct model* curr_model(void); void inc_posts(void); #define PAGES_PER_CHUNK 16 //"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, varcs; //odat, vdat, cdat,variant, 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 CHUNKS_FULL(STACK) ( (STACK).csp >= \ (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size) #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) \ { int i; \ (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \ (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ CSP_PUSH(STACK); \ for( i = 0; i < MAX_CHUNKS; i++){ \ (STACK).dsp[i] += pagesize; \ } \ } //Stack-specific macros (called directly from code (safety enforcement) #define INIT_ODAT() (INIT_STACK(ocs, struct odat)) #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 OCS_FULL() (CHUNKS_FULL(ocs)) #define INIT_VDAT() (INIT_STACK(vcs, struct vdat)) #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 VCS_FULL() (CHUNKS_FULL(vcs)) #define INIT_CDAT() (INIT_STACK(ccs, struct cdat)) #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 CCS_FULL() (CHUNKS_FULL(ccs)) #define INIT_VARIANT() (INIT_STACK(varcs, struct variant)) #define CURRENT_VARIANT() (CURRENT_DATP(varcs, struct variant)) #define VARIANT_FULL() (DATA_FULL(varcs, struct variant)) #define VARIANT_ALLOC() (ALLOC_DAT(varcs, struct variant)) #define VARCS_FULL() (CHUNKS_FULL(varcs)) #define INIT_LINK() (INIT_STACK(lcs, struct link)) #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 LCS_FULL() (CHUNKS_FULL(lcs)) #define INIT_POST() (INIT_STACK(rcs, struct ref)) #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 PCS_FULL() (CHUNKS_FULL(pcs)) #define INIT_REF() (INIT_STACK(rcs, 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)) #define RCS_FULL() (CHUNKS_FULL(rcs)) //Metadata #define CURRENT_SET() (CURRENT_CDAT()->set_list[CURRENT_CDAT()->num_sets]) //#define CURRENT_QUAD() (CURRENT_VARIANT()->quad_list[CURRENT_VARIANT()->num_quads]) //#define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) long pagesize; int num_cdats = 0; struct cdat* cdat_stack[MAX_CLASSES]; struct cdat** cdat_stackp; int num_odats = 0; int num_vdats = 0; int num_variants = 0; int num_refs = 0; int ss_ref_id = 0x0FFFFFFF; /* system space for ref_ids */ int num_posts = 0; int num_links = 0; /* The initalization function of the IR. */ int ir_init() { char root[4] = "root"; pagesize = sysconf(_SC_PAGESIZE); INIT_CDAT(); *cdat_stackp = CURRENT_CDAT(); memmove((*cdat_stackp)->name, root, 32); INIT_ODAT(); INIT_VDAT(); INIT_VARIANT(); INIT_LINK(); INIT_REF(); INIT_POST(); return 0; } void ir_quit() { int i; for(i = 0; i < CHUNKS_LEN(ccs) ; i++) { free(ccs.chunks[i]); } for(i = 0; i < CHUNKS_LEN(ocs); i++) { free(ocs.chunks[i]); } for(i = 0; i < CHUNKS_LEN(vcs) ; i++) { free(vcs.chunks[i]); } for(i = 0; i < CHUNKS_LEN(rcs); i++) { free(rcs.chunks[i]); } for(i = 0; i < CHUNKS_LEN(lcs); i++) { free(lcs.chunks[i]); } for(i = 0; i < CHUNKS_LEN(pcs); i++) { free(pcs.chunks[i]); } } struct cdat* alloc_cdat() { num_cdats++; if(CDAT_FULL()) { if(CCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats); exit(EXIT_FAILURE); } else CSP_PUSH(ccs); } else CDAT_ALLOC(); return CURRENT_CDAT(); } //these should probably be inline struct odat* alloc_odat () { num_odats++; if(ODAT_FULL()) { if(!OCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats); exit(EXIT_FAILURE); } else CSP_PUSH(ocs); } else ODAT_ALLOC(); return CURRENT_ODAT(); } struct vdat* alloc_vdat () { num_vdats++; if(VDAT_FULL()) { if(!VCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats); exit(EXIT_FAILURE); } else CSP_PUSH(vcs); } else VDAT_ALLOC(); return CURRENT_VDAT(); } struct variant* alloc_variant () { num_variants++; if(VARIANT_FULL()) { if(!VARCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) variants ", num_variants); exit(EXIT_FAILURE); } else CSP_PUSH(varcs); } else VARIANT_ALLOC(); return CURRENT_VARIANT(); } struct link* alloc_link () { num_links++; if(LDAT_FULL()) { if(!LCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) links ", num_links); exit(EXIT_FAILURE); } else CSP_PUSH(lcs); } else LDAT_ALLOC(); return CURRENT_LINK(); } struct ref* alloc_ref () { num_refs++; if(REF_FULL()) { if(!RCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs); exit(EXIT_FAILURE); } else 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()) { if(!PCS_FULL()) { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts); exit(EXIT_FAILURE); } else CSP_PUSH(pcs); } else POST_ALLOC(); } struct cdat* curr_cdat () { return (*cdat_stackp); } struct odat* curr_odat () { return CURRENT_ODAT(); } struct vdat* curr_vdat () { return CURRENT_VDAT(); } struct set* curr_set () { return &CURRENT_SET(); } struct ref* curr_ref () { return CURRENT_REF(); } struct variant* curr_variant () { return CURRENT_VARIANT(); } /* struct quad* */ /* curr_quad */ /* () */ /* { */ /* return &CURRENT_QUAD(); */ /* } */ /* struct model* */ /* curr_model */ /* () */ /* { */ /* return &CURRENT_MODEL(); */ /* } */