static void write_trace (trc_env_t *env, size_t trace_size, ref_t *trace) { string_index_t si = SIcreate(); size_t i = 1; int last; int src[env->N]; write_trace_step_t ctx; ctx.env = env; ctx.dst = env->get_state (trace[0], env->get_state_arg); ctx.dst_no = SIputC (si, (const char *)&trace[0], sizeof(ref_t)); // write initial state write_trace_state (env, ctx.dst); while (i < trace_size) { memcpy(src, ctx.dst, sizeof(int[env->N])); ctx.src_no = ctx.dst_no; ctx.dst = env->get_state (trace[i], env->get_state_arg); ctx.dst_no = last = SIlookupC(si, (const char *)&trace[i], sizeof(ref_t)); if (ctx.dst_no == SI_INDEX_FAILED) { ctx.dst_no = SIputC (si, (const char *)&trace[i], sizeof(ref_t)); } write_trace_step (&ctx, src); // write step if (last == SI_INDEX_FAILED) write_trace_state (env, ctx.dst); // write dst i++; } SIdestroy (&si); }
archive_t arch_zip_read(const char* name,int buf){ archive_t arch=(archive_t)HREmalloc(NULL,sizeof(struct archive_s)); arch_init(arch); int err; arch->archive=zip_open(name,ZIP_CHECKCONS,&err); if (arch->archive==NULL){ char errstr[1024]; zip_error_to_str(errstr, sizeof(errstr), err, errno); Abort("cannot open zip archive `%s': %s\n",name , errstr); } arch->stream_index=SIcreate(); #ifdef LIBZIP_VERSION int count=zip_get_num_entries(arch->archive,0); #else int count=zip_get_num_files(arch->archive); #endif for(int i=0;i<count;i++){ struct zip_stat sb; int res=zip_stat_index(arch->archive,i,0,&sb); if (res<0) { Abort("cannot stat zip archive: %s\n",zip_strerror(arch->archive)); } SIputAt(arch->stream_index,sb.name,i); Print(infoShort,"stream %d is %s",i,sb.name); } arch->procs.contains=zip_contains; arch->procs.read=hre_zip_read; arch->procs.read_raw=hre_zip_read_raw; arch->procs.enumerator=zip_enum; arch->procs.close=hre_zip_close; arch->buf=buf; return arch; }
value_table_t HREcreateTable(hre_context_t ctx,const char* name){ if (HREpeers(ctx)==1) return chunk_table_create(ctx,(char*)name); value_table_t vt=VTcreateBase((char*)name,sizeof(struct value_table_s)); VTdestroySet(vt,destroy); VTputChunkSet(vt,put_chunk); VTputAtChunkSet(vt,put_at_chunk); VTgetChunkSet(vt,get_chunk); VTgetCountSet(vt,get_count); vt->index=SIcreate(); vt->ctx=ctx; vt->msg_pending=0; uint32_t request_tag=HREactionCreate(ctx,1,CHUNK_BUFFER_SIZE,request_action,vt); uint32_t answer_tag=HREactionCreate(ctx,0,CHUNK_BUFFER_SIZE,answer_action,vt); vt->msg=HREnewMessage(ctx,CHUNK_BUFFER_SIZE); if (HREme(ctx)==0){ vt->msg->tag=answer_tag; vt->msg->comm=0; } else { vt->msg->tag=request_tag; vt->msg->comm=1; } vt->msg->source=HREme(ctx); vt->msg->target=0; vt->msg->ready=hre_ready_decr; vt->msg->ready_ctx=&vt->msg_pending; HREbarrier(ctx); return vt; }
static void *new_string_index(void* context){ (void)context; Warning(info,"creating a new string index"); return SIcreate(); }
static void *new_string_index(void* context){ (void)context; return SIcreate(); }
void ETFloadGreyboxModel(model_t model, const char *name) { gb_context_t ctx=(gb_context_t)RTmalloc(sizeof(struct grey_box_context)); GBsetContext(model,ctx); etf_model_t etf=etf_parse_file(name); lts_type_t ltstype=etf_type(etf); int state_length=lts_type_get_state_length(ltstype); ctx->edge_labels=lts_type_get_edge_label_count(ltstype); if (ctx->edge_labels>1) { ctx->label_idx=SIcreate(); } else { ctx->label_idx=NULL; } GBsetLTStype(model,ltstype); matrix_t* p_dm_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_read_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_write_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); dm_create(p_dm_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_read_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_write_info, etf_trans_section_count(etf), state_length); ctx->trans_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(string_index_t)); ctx->trans_table=(matrix_table_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(matrix_table_t)); for(int i=0; i < dm_nrows(p_dm_info); i++) { Warning(infoLong,"parsing table %d",i); etf_rel_t trans=etf_trans_section(etf,i); int used[state_length]; int src[state_length]; int dst[state_length]; int lbl[ctx->edge_labels]; int proj[state_length]; ETFrelIterate(trans); if (!ETFrelNext(trans,src,dst,lbl)){ Abort("unexpected empty transition section"); } int len=0; for(int j=0;j<state_length;j++){ if (src[j]) { proj[len]=j; Warning(debug,"pi[%d]=%d",len,proj[len]); len++; dm_set(p_dm_info, i, j); used[j]=1; } else { used[j]=0; } } Warning(infoLong,"length is %d",len); ctx->trans_key_idx[i]=SIcreate(); ctx->trans_table[i]=MTcreate(3); int src_short[len]; int dst_short[len]; uint32_t row[3]; do { /* * If an element is non-zero, we always consider it a read. If the * value is changed for at least one transition in a group then * we also consider it a write. Note that this could be slightly * optimized by omitting those elements from read where the value * varies over all possible inputs. */ for(int k=0;k<state_length;k++) { if (src[k] != 0) { dm_set(p_dm_read_info, i, k); if (src[k] != dst[k]) dm_set(p_dm_write_info, i, k); } } for(int k=0;k<state_length;k++) { if(used[k]?(src[k]==0):(src[k]!=0)){ Abort("inconsistent section in src vector"); } } for(int k=0;k<len;k++) src_short[k]=src[proj[k]]-1; for(int k=0;k<state_length;k++) { if(used[k]?(dst[k]==0):(dst[k]!=0)){ Abort("inconsistent section in dst vector"); } } for(int k=0;k<len;k++) dst_short[k]=dst[proj[k]]-1; row[0]=(uint32_t)SIputC(ctx->trans_key_idx[i],(char*)src_short,len<<2); switch(ctx->edge_labels){ case 0: row[2]=0; break; case 1: row[2]=(uint32_t)lbl[0]; break; default: row[2]=(uint32_t)SIputC(ctx->label_idx,(char*)lbl,(ctx->edge_labels)<<2); break; } row[1]=(int32_t)SIputC(ctx->trans_key_idx[i],(char*)dst_short,len<<2); MTaddRow(ctx->trans_table[i],row); } while(ETFrelNext(trans,src,dst,lbl)); Warning(infoLong,"table %d has %d states and %d transitions", i,SIgetCount(ctx->trans_key_idx[i]),ETFrelCount(trans)); ETFrelDestroy(&trans); MTclusterBuild(ctx->trans_table[i],0,SIgetCount(ctx->trans_key_idx[i])); } GBsetDMInfo(model, p_dm_info); /* * Set these again when ETF supports read, write and copy. GBsetDMInfoRead(model, p_dm_read_info); GBsetDMInfoMustWrite(model, p_dm_write_info); GBsetSupportsCopy(model); // no may-write so we support copy. */ GBsetNextStateShort(model,etf_short); matrix_t *p_sl_info = RTmalloc(sizeof *p_sl_info); dm_create(p_sl_info, etf_map_section_count(etf), state_length); ctx->label_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_sl_info)*sizeof(string_index_t)); ctx->label_data=(int**)RTmalloc(dm_nrows(p_sl_info)*sizeof(int*)); for(int i=0;i<dm_nrows(p_sl_info);i++){ Warning(infoLong,"parsing map %d",i); etf_map_t map=etf_get_map(etf,i); int used[state_length]; int state[state_length]; int value; ETFmapIterate(map); if (!ETFmapNext(map,state,&value)){ Abort("Unexpected empty map"); } int len=0; for(int j=0;j<state_length;j++){ if (state[j]) { used[len]=j; len++; dm_set(p_sl_info, i, j); } } int*proj=(int*)RTmalloc(len*sizeof(int)); for(int j=0;j<len;j++) proj[j]=used[j]; for(int j=0;j<state_length;j++) used[j]=state[j]; string_index_t key_idx=SIcreate(); int *data=(int*)RTmalloc(ETFmapCount(map)*sizeof(int)); int key[len]; do { for(int k=0;k<state_length;k++) { if(used[k]?(state[k]==0):(state[k]!=0)){ Abort("inconsistent map section"); } } for(int k=0;k<len;k++) key[k]=state[proj[k]]-1; data[SIputC(key_idx,(char*)key,len<<2)]=value; } while(ETFmapNext(map,state,&value)); ctx->label_key_idx[i]=key_idx; ctx->label_data[i]=data; } GBsetStateLabelInfo(model, p_sl_info); GBsetStateLabelShort(model,etf_state_short); GBsetTransitionInGroup(model,etf_transition_in_group); int type_count=lts_type_get_type_count(ltstype); for(int i=0;i<type_count;i++){ Warning(infoLong,"Setting values for type %d (%s)",i,lts_type_get_type(ltstype,i)); int count=etf_get_value_count(etf,i); for(int j=0;j<count;j++){ GBchunkPutAt(model,i,etf_get_value(etf,i,j),j); } } int state[state_length]; etf_get_initial(etf,state); GBsetInitialState(model,state); }