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; }
void TQwhile(hre_task_queue_t queue,int*condition){ if (HREpeers(queue->ctx)==1 && (*condition)) { Abort("deadlock detected"); } queue->mode=Immediate; TaskFlush(queue); HREyieldWhile(queue->ctx,condition); queue->mode=Lazy; }
void lts_file_sync(lts_file_t lts){ lts=SYSTEM(lts); int peers=HREpeers(lts->ctx); HREreduce(lts->ctx,1,<s->roots,<s->roots,UInt32,Sum); HREreduce(lts->ctx,peers,lts->states,lts->states,UInt32,Sum); HREreduce(lts->ctx,peers,lts->edges,lts->edges,UInt64,Sum); HREreduce(lts->ctx,peers,lts->max_src_p1,lts->max_src_p1,UInt32,Max); HREreduce(lts->ctx,peers,lts->max_dst_p1,lts->max_dst_p1,UInt32,Max); }
static void* thread_main(void*arg){ hre_context_t context=(hre_context_t)arg; HREprocessSet(context); HREglobalSet(context); set_label("%s(%2d/%2d)",HREappName(),HREme(context),HREpeers(context)); Debug("calling main..."); int argc=1; char *argv[2]={strdup(HREpathName()),NULL}; main(argc,argv); return NULL; }
static void TaskFlush(hre_task_queue_t queue){ int max=array_size(queue->man); int pos; int peers=HREpeers(queue->ctx); for(pos=0;pos<max;pos++) if (queue->task[pos]) { for(int i=0;i<peers;i++){ if (queue->task[pos]->msg[i] && queue->task[pos]->msg[i]->tail){ TaskSend(queue->task[pos],i); } } } }
int main(int argc, char *argv[]){ char* files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Tool for transforming labeled transition systems\n\nOptions"); lts_lib_setup(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); int me=HREme(HREglobal()); int peers=HREpeers(HREglobal()); if (peers>1) Abort("parallelizing this tool is future work");(void)me; string_set_t label_set=NULL; if (label_filter!=NULL){ label_set=SSMcreateSWPset(label_filter); } switch(task){ case Undefined: Abort("task unspecified"); case LTScopy: if (files[1]==NULL) Abort("second argument required for copy."); Print(infoShort,"streaming copy from %s to %s",files[0],files[1]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); rd_seg=lts_file_get_segments(in); if (wr_seg==0) { wr_seg=rd_seg; } else { Abort("on-the-fly changing the number of segments is future work"); } lts_file_t out; if (label_set==NULL){ out=lts_file_create(files[1],ltstype,wr_seg,in); } else { out=lts_file_create_filter(files[1],ltstype,label_set,wr_seg,in); } int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } lts_file_copy(in,out); lts_file_close(out); lts_file_close(in); break; case LTSrdwr: if (files[1]==NULL) Abort("second argument required for rdwr."); Print(infoShort,"loading from %s",files[0]); lts_t lts=lts_create(); lts_read(files[0],lts); if (encode) { Print(infoShort,"single edge label encoding"); lts=lts_encode_edge(lts); } if (bfs_reorder) { Print(infoShort,"reindexing LTS in BFS order"); lts_bfs_reorder(lts); } Print(infoShort,"storing in %s",files[1]); if(wr_seg==0) wr_seg=1; lts_write(files[1],lts,label_set,wr_seg); break; case LTSindex:{ if (peers>1) Abort("parallelizing this tool is future work"); if (files[1]==NULL) Abort("second argument required for index."); Print(infoShort,"opening %s",files[0]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); int segments=lts_file_get_segments(in); lts_file_t settings=lts_get_template(in); if (lts_file_get_edge_owner(settings)!=SourceOwned) Abort("bad edge owner"); lts_file_set_dest_mode(settings,Index); lts_file_set_init_mode(settings,Index); Print(infoShort,"creating %s",files[1]); lts_file_t out=lts_file_create(files[1],ltstype,segments,settings); int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } treedbs_t db[segments]; int SV=lts_type_get_state_length(ltstype); int SL=lts_type_get_state_label_count(ltstype); int K=lts_type_get_edge_label_count(ltstype); for(int i=0;i<segments;i++){ Print(info,"loading and copying states of segment %d",i); uint32_t state[SV]; uint32_t label[SL]; db[i]=TreeDBScreate(SV); int idx=0; while(lts_read_state(in,&i,state,label)){ int tmp=TreeFold(db[i],(int*)state); if (idx!=tmp){ Abort("unexpected index %u != %u",tmp,idx); } idx++; lts_write_state(out,i,(int*)state,label); } } Print(info,"converting initial states"); { uint32_t seg; uint32_t state[SV]; while(lts_read_init(in,(int*)&seg,state)){ int idx=TreeFold(db[seg],(int*)state); lts_write_init(out,seg,&idx); } } for(int i=0;i<segments;i++){ Print(info,"converting edges of segment %d",i); uint32_t src_state[1]; uint32_t dst_seg; uint32_t dst_state[SV]; uint32_t label[K]; while(lts_read_edge(in,&i,src_state,(int*)&dst_seg,dst_state,label)){ int idx=TreeFold(db[dst_seg],(int*)dst_state); lts_write_edge(out,i,src_state,dst_seg,&idx,label); } } lts_file_close(out); lts_file_close(in); } } Print(infoShort,"done"); HREexit(LTSMIN_EXIT_SUCCESS); }
int TQwait(hre_task_queue_t queue){ if (HREpeers(queue->ctx)==1) return 0; Debug("enter wait"); queue->wait_cancelled=0; queue->status=Dirty; queue->mode=Immediate; TaskFlush(queue); struct term_msg* msg_in=&queue->term_in; struct term_msg* msg_out=(struct term_msg*)queue->msg->buffer; if (HREme(queue->ctx)==0) { queue->status=Dirty; int round=0; while(queue->status!=Terminated) { queue->wait_pending=queue->recv_pending; HREyieldWhile(queue->ctx,&queue->wait_pending); if (queue->wait_cancelled){ Debug("wait cancelled 1"); queue->status=Active; queue->mode=Lazy; return 1; // wait has been cancelled. } switch(queue->status){ case Idle: case Dirty: if (msg_in->status==Terminated){ msg_in->status=Dirty; queue->status=Terminated; break; } if (queue->send_pending) { HREyieldWhile(queue->ctx,&queue->send_pending); if (queue->wait_cancelled){ Debug("wait cancelled 2"); queue->status=Active; queue->mode=Lazy; return 1; // wait has been cancelled. } } if (queue->status==Idle && msg_in->status==Idle && msg_in->sent==msg_in->recv){ msg_out->status=Terminated; Debug("termination detected in %d rounds",round); queue->send_pending=1; queue->recv_pending=1; HREpostSend(queue->msg); break; } queue->status=Idle; msg_out->status=Idle; msg_out->sent=queue->sent; msg_out->recv=queue->recv; queue->status=Idle; round++; Debug("starting detection round %d",round); queue->send_pending=1; queue->recv_pending=1; HREpostSend(queue->msg); break; case Active: Abort("should not be active in this loop") case Terminated: Abort("should not be terminated in this loop") default: Abort("missing case"); } } queue->status=Active; } else {
int lts_file_owned(lts_file_t lts,int nth){ int me=HREme(SYSTEM(lts)->ctx); int peers=HREpeers(SYSTEM(lts)->ctx); return me+peers*nth; }
int lts_file_owned_count(lts_file_t lts){ int me=HREme(SYSTEM(lts)->ctx); int peers=HREpeers(SYSTEM(lts)->ctx); int N=SYSTEM(lts)->segments; return (N+peers-me-1)/peers; }
} int SLTSsegmentNumber(seg_lts_t lts){ return lts->seg_no; } hre_task_queue_t SLTSgetQueue(seg_lts_t lts){ return lts->task_queue; } seg_lts_t SLTScreate(lts_type_t signature,hre_task_queue_t task_queue,seg_lts_layout_t layout){ seg_lts_t lts=RT_NEW(struct seg_lts_s); lts->sig=signature; lts->task_queue=task_queue; lts->seg_no=HREme(TQcontext(task_queue)); lts->seg_count=HREpeers(TQcontext(task_queue)); lts->state_length=lts_type_get_state_length(signature); lts->state_labels=lts_type_get_state_label_count(signature); lts->edge_labels=lts_type_get_edge_label_count(signature); lts->layout=layout; lts->vt_count=lts_type_get_type_count(signature); lts->vt=RTmalloc(lts->vt_count*sizeof(value_table_t)); for(int i=0;i<lts->vt_count;i++) { char *type_name=lts_type_get_type(signature,i); lts->vt[i]=HREcreateTable(TQcontext(task_queue),type_name); } return lts; } int SLTSstateCount(seg_lts_t lts){ return lts->state_count;