2020-08-17 13:26:18 +00:00
package sectorstorage
2020-07-09 11:49:01 +00:00
import (
"sync"
2020-08-17 13:26:18 +00:00
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
2020-07-09 11:49:01 +00:00
)
func ( a * activeResources ) withResources ( id WorkerID , wr storiface . WorkerResources , r Resources , locker sync . Locker , cb func ( ) error ) error {
2020-08-28 19:38:21 +00:00
for ! a . canHandleRequest ( r , id , "withResources" , wr ) {
2020-07-09 11:49:01 +00:00
if a . cond == nil {
a . cond = sync . NewCond ( locker )
}
a . cond . Wait ( )
}
a . add ( wr , r )
err := cb ( )
a . free ( wr , r )
if a . cond != nil {
a . cond . Broadcast ( )
}
return err
}
func ( a * activeResources ) add ( wr storiface . WorkerResources , r Resources ) {
2020-10-28 18:52:33 +00:00
if r . CanGPU {
a . gpuUsed = true
}
2020-09-30 22:27:54 +00:00
a . cpuUse += r . Threads ( wr . CPUs )
2020-07-09 11:49:01 +00:00
a . memUsedMin += r . MinMemory
a . memUsedMax += r . MaxMemory
}
func ( a * activeResources ) free ( wr storiface . WorkerResources , r Resources ) {
if r . CanGPU {
a . gpuUsed = false
}
2020-09-30 22:27:54 +00:00
a . cpuUse -= r . Threads ( wr . CPUs )
2020-07-09 11:49:01 +00:00
a . memUsedMin -= r . MinMemory
a . memUsedMax -= r . MaxMemory
}
2020-08-28 19:38:21 +00:00
func ( a * activeResources ) canHandleRequest ( needRes Resources , wid WorkerID , caller string , res storiface . WorkerResources ) bool {
2020-07-09 11:49:01 +00:00
// TODO: dedupe needRes.BaseMinMemory per task type (don't add if that task is already running)
minNeedMem := res . MemReserved + a . memUsedMin + needRes . MinMemory + needRes . BaseMinMemory
if minNeedMem > res . MemPhysical {
2020-08-28 19:38:21 +00:00
log . Debugf ( "sched: not scheduling on worker %d for %s; not enough physical memory - need: %dM, have %dM" , wid , caller , minNeedMem / mib , res . MemPhysical / mib )
2020-07-09 11:49:01 +00:00
return false
}
maxNeedMem := res . MemReserved + a . memUsedMax + needRes . MaxMemory + needRes . BaseMinMemory
if maxNeedMem > res . MemSwap + res . MemPhysical {
2020-08-28 19:38:21 +00:00
log . Debugf ( "sched: not scheduling on worker %d for %s; not enough virtual memory - need: %dM, have %dM" , wid , caller , maxNeedMem / mib , ( res . MemSwap + res . MemPhysical ) / mib )
2020-07-09 11:49:01 +00:00
return false
}
2020-09-30 22:27:54 +00:00
if a . cpuUse + needRes . Threads ( res . CPUs ) > res . CPUs {
log . Debugf ( "sched: not scheduling on worker %d for %s; not enough threads, need %d, %d in use, target %d" , wid , caller , needRes . Threads ( res . CPUs ) , a . cpuUse , res . CPUs )
return false
2020-07-09 11:49:01 +00:00
}
if len ( res . GPUs ) > 0 && needRes . CanGPU {
if a . gpuUsed {
2020-08-28 19:38:21 +00:00
log . Debugf ( "sched: not scheduling on worker %d for %s; GPU in use" , wid , caller )
2020-07-09 11:49:01 +00:00
return false
}
}
return true
}
func ( a * activeResources ) utilization ( wr storiface . WorkerResources ) float64 {
var max float64
cpu := float64 ( a . cpuUse ) / float64 ( wr . CPUs )
max = cpu
memMin := float64 ( a . memUsedMin + wr . MemReserved ) / float64 ( wr . MemPhysical )
if memMin > max {
max = memMin
}
memMax := float64 ( a . memUsedMax + wr . MemReserved ) / float64 ( wr . MemPhysical + wr . MemSwap )
if memMax > max {
max = memMax
}
return max
}
2020-08-31 11:31:11 +00:00
func ( wh * workerHandle ) utilization ( ) float64 {
wh . lk . Lock ( )
u := wh . active . utilization ( wh . info . Resources )
u += wh . preparing . utilization ( wh . info . Resources )
wh . lk . Unlock ( )
wh . wndLk . Lock ( )
for _ , window := range wh . activeWindows {
u += window . allocated . utilization ( wh . info . Resources )
}
wh . wndLk . Unlock ( )
return u
}