github.com/DARA-Project/GoDist-Scheduler@v0.0.0-20201030134746-668de4acea0d/tools/shiviz_converter.go (about)

     1  package main
     2  
     3  import (
     4  	"dara"
     5  	"github.com/DARA-Project/GoDist-Scheduler/common"
     6  	"github.com/DistributedClocks/GoVector/govec/vclock"
     7  	"log"
     8  	"os"
     9  	"strconv"
    10  )
    11  
    12  func initialize_shiviz_file(filename string) (*os.File, error) {
    13  	f, err := os.Create(filename)
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  	n, err := f.WriteString("(?<host>\\S*) (?<clock>{.*})\\n(?<event>.*)\n\n")
    18  	if err != nil {
    19  		f.Close()
    20  		return nil, err
    21  	}
    22  	log.Println("Initialized shiviz log file by writing", n, "bytes")
    23  	return f, nil
    24  }
    25  
    26  func uniqueThreadID(procID int, goid int) string {
    27  	return strconv.Itoa(procID) + ":" + strconv.Itoa(goid)
    28  }
    29  
    30  func parse_schedule(schedule *dara.Schedule, filename string) error {
    31  	f, err := initialize_shiviz_file(filename)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	defer f.Close()
    36  	clocks := make(map[string]*vclock.VClock)
    37  	routine_names := make(map[string]string)
    38  	coverage_map := make(map[int]string)
    39  	prop_failure_map := make(map[int]string)
    40  	for _, covEvent := range schedule.CovEvents {
    41  		coverage_map[covEvent.EventIndex] = common.CoverageString(&covEvent)
    42  	}
    43  	for _, propEvent := range schedule.PropEvents {
    44  		prop_failure_map[propEvent.EventIndex] = common.PropCheckString(&propEvent)
    45  	}
    46  	curr_running_routine := uniqueThreadID(1, 1)
    47  	current_process := 1
    48  	for idx, event := range schedule.LogEvents {
    49  		var coverage string
    50  		if v, ok := coverage_map[idx]; ok {
    51  			coverage = v
    52  		}
    53  		var propfailures string
    54  		if v, ok := prop_failure_map[idx]; ok {
    55  			propfailures = v
    56  		}
    57  		goroutine_string := common.GoRoutineNameString(event.P, event.G)
    58  		uniqueID := uniqueThreadID(event.P, event.G.Gid)
    59  		if _, ok := routine_names[uniqueID]; !ok {
    60  			routine_names[uniqueID] = goroutine_string
    61  		}
    62  		if vc, ok := clocks[uniqueID]; !ok {
    63  			clock := vclock.New()
    64  			clocks[uniqueID] = &clock
    65  			clock.Tick(goroutine_string)
    66  			// Tick the goroutine that is getting off and merge the vector
    67  			// clock of the old goroutine with the newly launched goroutine
    68  			if (event.Type == dara.SCHED_EVENT && curr_running_routine != uniqueID) || (current_process != event.P) {
    69  				prev_routine_clock := clocks[curr_running_routine]
    70  				prev_routine_name := routine_names[curr_running_routine]
    71  				prev_routine_clock.Tick(prev_routine_name)
    72  				eventString := common.ConciseEventString(&event)
    73  				if coverage != "" {
    74  					eventString += "; Coverage: " + coverage
    75  				}
    76  				if propfailures != "" {
    77  					eventString += "; PropFailures: " + propfailures
    78  				}
    79  				n, err := f.WriteString(prev_routine_name + " " + prev_routine_clock.ReturnVCString() + "\n" +
    80  					"Switching routines" + "\n")
    81  				if err != nil {
    82  					return err
    83  				}
    84  				clock.Merge(*clocks[curr_running_routine])
    85  				log.Printf("Wrote %d bytes\n", n)
    86  			}
    87  			eventString := common.ConciseEventString(&event)
    88  			if coverage != "" {
    89  				eventString += "; Coverage: " + coverage
    90  			}
    91  			if propfailures != "" {
    92  				eventString += "; PropFailures: " + propfailures
    93  			}
    94  			n, err := f.WriteString(goroutine_string + " " + clock.ReturnVCString() + "\n" +
    95  				eventString + "\n")
    96  			if err != nil {
    97  				return err
    98  			}
    99  			log.Printf("Wrote %d bytes\n", n)
   100  		} else {
   101  			vc.Tick(goroutine_string)
   102  			// Tick the goroutine that is getting off and merge the vector
   103  			// clock of the old goroutine with the newly launched goroutine
   104  			if (event.Type == dara.SCHED_EVENT && curr_running_routine != uniqueID) || (current_process != event.P) {
   105  				prev_routine_clock := clocks[curr_running_routine]
   106  				prev_routine_name := routine_names[curr_running_routine]
   107  				prev_routine_clock.Tick(prev_routine_name)
   108  				eventString := common.ConciseEventString(&event)
   109  				if coverage != "" {
   110  					eventString += "; Coverage: " + coverage
   111  				}
   112  				if propfailures != "" {
   113  					eventString += "; PropFailures: " + propfailures
   114  				}
   115  				n, err := f.WriteString(prev_routine_name + " " + prev_routine_clock.ReturnVCString() + "\n" +
   116  					"Switching routines" + "\n")
   117  				if err != nil {
   118  					return err
   119  				}
   120  				vc.Merge(*clocks[curr_running_routine])
   121  				log.Printf("Wrote %d bytes\n", n)
   122  			}
   123  			eventString := common.ConciseEventString(&event)
   124  			if coverage != "" {
   125  				eventString += "; Coverage: " + coverage
   126  			}
   127  			if propfailures != "" {
   128  				eventString += "; PropFailures: " + propfailures
   129  			}
   130  			n, err := f.WriteString(goroutine_string + " " + vc.ReturnVCString() + "\n" +
   131  				eventString + "\n")
   132  			if err != nil {
   133  				return err
   134  			}
   135  			log.Printf("Wrote %d bytes\n", n)
   136  		}
   137  		if event.Type != dara.THREAD_EVENT {
   138  			curr_running_routine = uniqueID
   139  		}
   140  		current_process = event.P
   141  	}
   142  	return nil
   143  }
   144  
   145  func main() {
   146  	if len(os.Args) != 3 {
   147  		log.Fatal("Usage: go run shiviz_converter.go <schedule_filename> <shiviz_filename>")
   148  	}
   149  	filename := os.Args[1]
   150  	shiviz_filename := os.Args[2]
   151  	schedule, err := common.ReadSchedule(filename)
   152  	if err != nil {
   153  		log.Fatal(err)
   154  	}
   155  	log.Println("Length of the schedule is ", len(schedule.LogEvents))
   156  	err = parse_schedule(schedule, shiviz_filename)
   157  	if err != nil {
   158  		log.Fatal(err)
   159  	}
   160  }