main: add -p flag to set parallelism

This is very useful for debugging.
Этот коммит содержится в:
Ayke van Laethem 2021-09-22 14:00:51 +02:00 коммит произвёл Ron Evans
родитель 79bdd3f79a
коммит c638f03b3c
5 изменённых файлов: 19 добавлений и 6 удалений

Просмотреть файл

@ -462,7 +462,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
outext := filepath.Ext(outpath) outext := filepath.Ext(outpath)
if outext == ".o" || outext == ".bc" || outext == ".ll" { if outext == ".o" || outext == ".bc" || outext == ".ll" {
// Run jobs to produce the LLVM module. // Run jobs to produce the LLVM module.
err := runJobs(programJob) err := runJobs(programJob, config.Options.Parallelism)
if err != nil { if err != nil {
return err return err
} }
@ -686,7 +686,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
// Run all jobs to compile and link the program. // Run all jobs to compile and link the program.
// Do this now (instead of after elf-to-hex and similar conversions) as it // Do this now (instead of after elf-to-hex and similar conversions) as it
// is simpler and cannot be parallelized. // is simpler and cannot be parallelized.
err = runJobs(linkJob) err = runJobs(linkJob, config.Options.Parallelism)
if err != nil { if err != nil {
return err return err
} }

Просмотреть файл

@ -71,7 +71,16 @@ func (job *compileJob) readyToRun() bool {
// It runs all jobs in the order of the dependencies slice, depth-first. // It runs all jobs in the order of the dependencies slice, depth-first.
// Therefore, if some jobs are preferred to run before others, they should be // Therefore, if some jobs are preferred to run before others, they should be
// ordered as such in the job dependencies. // ordered as such in the job dependencies.
func runJobs(job *compileJob) error { func runJobs(job *compileJob, parallelism int) error {
if parallelism == 0 {
// Have a default, if the parallelism isn't set. This is useful for
// tests.
parallelism = runtime.NumCPU()
}
if parallelism < 1 {
return fmt.Errorf("-p flag must be at least 1, provided -p=%d", parallelism)
}
// Create a slice of jobs to run, where all dependencies are run in order. // Create a slice of jobs to run, where all dependencies are run in order.
jobs := []*compileJob{} jobs := []*compileJob{}
addedJobs := map[*compileJob]struct{}{} addedJobs := map[*compileJob]struct{}{}
@ -94,7 +103,7 @@ func runJobs(job *compileJob) error {
defer close(workerChan) defer close(workerChan)
// Start a number of workers. // Start a number of workers.
for i := 0; i < runtime.NumCPU(); i++ { for i := 0; i < parallelism; i++ {
if jobRunnerDebug { if jobRunnerDebug {
fmt.Println("## starting worker", i) fmt.Println("## starting worker", i)
} }
@ -109,7 +118,7 @@ func runJobs(job *compileJob) error {
for { for {
// If there are free workers, try starting a new job (if one is // If there are free workers, try starting a new job (if one is
// available). If it succeeds, try again to fill the entire worker pool. // available). If it succeeds, try again to fill the entire worker pool.
if numRunningJobs < runtime.NumCPU() { if numRunningJobs < parallelism {
jobToRun := nextJob(jobs) jobToRun := nextJob(jobs)
if jobToRun != nil { if jobToRun != nil {
// Start job. // Start job.

Просмотреть файл

@ -52,7 +52,7 @@ func (l *Library) Load(config *compileopts.Config, tmpdir string) (dir string, e
if err != nil { if err != nil {
return "", err return "", err
} }
err = runJobs(job) err = runJobs(job, config.Options.Parallelism)
return filepath.Dir(job.result), err return filepath.Dir(job.result), err
} }

Просмотреть файл

@ -31,6 +31,7 @@ type Options struct {
DumpSSA bool DumpSSA bool
VerifyIR bool VerifyIR bool
PrintCommands func(cmd string, args ...string) PrintCommands func(cmd string, args ...string)
Parallelism int // -p flag
Debug bool Debug bool
PrintSizes string PrintSizes string
PrintAllocs *regexp.Regexp // regexp string PrintAllocs *regexp.Regexp // regexp string

Просмотреть файл

@ -1118,6 +1118,7 @@ func main() {
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
printCommands := flag.Bool("x", false, "Print commands") printCommands := flag.Bool("x", false, "Print commands")
parallelism := flag.Int("p", runtime.GOMAXPROCS(0), "the number of build jobs that can run in parallel")
nodebug := flag.Bool("no-debug", false, "strip debug information") nodebug := flag.Bool("no-debug", false, "strip debug information")
ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)") ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)")
ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug")
@ -1190,6 +1191,7 @@ func main() {
PrintIR: *printIR, PrintIR: *printIR,
DumpSSA: *dumpSSA, DumpSSA: *dumpSSA,
VerifyIR: *verifyIR, VerifyIR: *verifyIR,
Parallelism: *parallelism,
Debug: !*nodebug, Debug: !*nodebug,
PrintSizes: *printSize, PrintSizes: *printSize,
PrintStacks: *printStacks, PrintStacks: *printStacks,
@ -1278,6 +1280,7 @@ func main() {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
config := &compileopts.Config{ config := &compileopts.Config{
Options: options,
Target: &compileopts.TargetSpec{ Target: &compileopts.TargetSpec{
Triple: *target, Triple: *target,
}, },