go-hep.org/x/hep@v0.38.1/fwk/cmd/fwk-cpu-cruncher/cruncher.go (about) 1 // Copyright ©2017 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "reflect" 10 "time" 11 12 "go-hep.org/x/hep/fwk" 13 ) 14 15 type CPUCruncher struct { 16 fwk.TaskBase 17 18 cpuch chan int64 19 quit chan struct{} 20 21 inputs []string 22 outputs []string 23 cpus []int64 24 } 25 26 func (tsk *CPUCruncher) Configure(ctx fwk.Context) error { 27 var err error 28 29 for _, input := range tsk.inputs { 30 if input == "" { 31 continue 32 } 33 err = tsk.DeclInPort(input, reflect.TypeOf(int64(0))) 34 if err != nil { 35 return err 36 } 37 } 38 39 for _, output := range tsk.outputs { 40 if output == "" { 41 continue 42 } 43 err = tsk.DeclOutPort(output, reflect.TypeOf(int64(0))) 44 if err != nil { 45 return err 46 } 47 } 48 49 if len(tsk.cpus) <= 0 { 50 msg := ctx.Msg() 51 msg.Errorf("invalid cpu-timings list: %v\n", tsk.cpus) 52 return fmt.Errorf("invalid cpu-timings") 53 } 54 55 return err 56 } 57 58 func (tsk *CPUCruncher) StartTask(ctx fwk.Context) error { 59 var err error 60 61 go func() { 62 i := 0 63 n := len(tsk.cpus) 64 for { 65 select { 66 case <-tsk.quit: 67 return 68 default: 69 if i >= n { 70 i = 0 71 } 72 v := tsk.cpus[i] 73 i++ 74 tsk.cpuch <- v 75 } 76 } 77 }() 78 79 return err 80 } 81 82 func (tsk *CPUCruncher) StopTask(ctx fwk.Context) error { 83 var err error 84 go func() { tsk.quit <- struct{}{} }() 85 return err 86 } 87 88 func (tsk *CPUCruncher) Process(ctx fwk.Context) error { 89 var err error 90 store := ctx.Store() 91 for _, input := range tsk.inputs { 92 _, err = store.Get(input) 93 if err != nil { 94 return err 95 } 96 } 97 98 cpu := <-tsk.cpuch 99 time.Sleep(time.Duration(cpu) * time.Microsecond) 100 101 for _, output := range tsk.outputs { 102 err = store.Put(output, cpu) 103 if err != nil { 104 return err 105 } 106 } 107 108 return err 109 } 110 111 func newCPUCruncher(typ, name string, mgr fwk.App) (fwk.Component, error) { 112 var err error 113 114 tsk := &CPUCruncher{ 115 TaskBase: fwk.NewTask(typ, name, mgr), 116 cpuch: make(chan int64), 117 quit: make(chan struct{}), 118 inputs: make([]string, 0), 119 outputs: make([]string, 0), 120 cpus: make([]int64, 0), 121 } 122 123 err = tsk.DeclProp("Inputs", &tsk.inputs) 124 if err != nil { 125 return nil, err 126 } 127 128 err = tsk.DeclProp("Outputs", &tsk.outputs) 129 if err != nil { 130 return nil, err 131 } 132 133 err = tsk.DeclProp("CPU", &tsk.cpus) 134 if err != nil { 135 return nil, err 136 } 137 138 return tsk, err 139 } 140 141 func init() { 142 fwk.Register(reflect.TypeOf(CPUCruncher{}), newCPUCruncher) 143 }