github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/os/exec_unix.go (about)

     1  // Copyright 2009 The Go 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  // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     6  
     7  package os
     8  
     9  import (
    10  	"dara"
    11  	"errors"
    12  	"runtime"
    13  	"syscall"
    14  	"time"
    15  )
    16  
    17  func (p *Process) wait() (ps *ProcessState, err error) {
    18  	if p.Pid == -1 {
    19  		return nil, syscall.EINVAL
    20  	}
    21  
    22  	// If we can block until Wait4 will succeed immediately, do so.
    23  	ready, err := p.blockUntilWaitable()
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  	if ready {
    28  		// Mark the process done now, before the call to Wait4,
    29  		// so that Process.signal will not send a signal.
    30  		p.setDone()
    31  		// Acquire a write lock on sigMu to wait for any
    32  		// active call to the signal method to complete.
    33  		p.sigMu.Lock()
    34  		p.sigMu.Unlock()
    35  	}
    36  
    37  	var status syscall.WaitStatus
    38  	var rusage syscall.Rusage
    39  	pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage)
    40  	if e != nil {
    41  		// DARA Instrumentation
    42  		if runtime.Is_dara_profiling_on() {
    43              runtime.Dara_Debug_Print(func() {
    44  			    print("[WAIT] : ")
    45  			    println(p.Pid)
    46              })
    47  			argInfo := dara.GeneralType{Type: dara.PROCESS, Integer: p.Pid}
    48  			retInfo1 := dara.GeneralType{Type: dara.POINTER, Unsupported: dara.UNSUPPORTEDVAL}
    49  			retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
    50  			syscallInfo := dara.GeneralSyscall{dara.DSYS_WAIT4, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}}
    51  			runtime.Report_Syscall_To_Scheduler(dara.DSYS_WAIT4, syscallInfo)
    52  		}
    53  		return nil, NewSyscallError("wait", e)
    54  	}
    55  	if pid1 != 0 {
    56  		p.setDone()
    57  	}
    58  	ps = &ProcessState{
    59  		pid:    pid1,
    60  		status: status,
    61  		rusage: &rusage,
    62  	}
    63  	// DARA Instrumentation
    64  	if runtime.Is_dara_profiling_on() {
    65          runtime.Dara_Debug_Print(func() {
    66  		    print("[WAIT] : ")
    67  		    println(p.Pid)
    68          })
    69  		argInfo := dara.GeneralType{Type: dara.PROCESS, Integer: p.Pid}
    70  		retInfo1 := dara.GeneralType{Type: dara.POINTER, Unsupported: dara.UNSUPPORTEDVAL}
    71  		retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
    72  		syscallInfo := dara.GeneralSyscall{dara.DSYS_WAIT4, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}}
    73  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_WAIT4, syscallInfo)
    74  	}
    75  	return ps, nil
    76  }
    77  
    78  var errFinished = errors.New("os: process already finished")
    79  
    80  func (p *Process) signal(sig Signal) error {
    81  	if p.Pid == -1 {
    82  		return errors.New("os: process already released")
    83  	}
    84  	if p.Pid == 0 {
    85  		return errors.New("os: process not initialized")
    86  	}
    87  	p.sigMu.RLock()
    88  	defer p.sigMu.RUnlock()
    89  	if p.done() {
    90  		return errFinished
    91  	}
    92  	s, ok := sig.(syscall.Signal)
    93  	if !ok {
    94  		return errors.New("os: unsupported signal type")
    95  	}
    96  	// DARA Instrumentation
    97  	if runtime.Is_dara_profiling_on() {
    98          runtime.Dara_Debug_Print(func() {
    99  		    print("[KILL] : ")
   100  		    print(p.Pid)
   101  		    print(" ")
   102  		    println(s.String())
   103          })
   104  		argInfo1 := dara.GeneralType{Type: dara.PROCESS, Integer: p.Pid}
   105  		argInfo2 := dara.GeneralType{Type: dara.SIGNAL}
   106          copy(argInfo2.String[:], s.String())
   107  		retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL}
   108  		syscallInfo :=  dara.GeneralSyscall{dara.DSYS_KILL, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}}
   109  		runtime.Report_Syscall_To_Scheduler(dara.DSYS_KILL, syscallInfo)
   110  	}
   111  	if e := syscall.Kill(p.Pid, s); e != nil {
   112  		if e == syscall.ESRCH {
   113  			return errFinished
   114  		}
   115  		return e
   116  	}
   117  	return nil
   118  }
   119  
   120  func (p *Process) release() error {
   121  	// NOOP for unix.
   122  	p.Pid = -1
   123  	// no need for a finalizer anymore
   124  	runtime.SetFinalizer(p, nil)
   125  	return nil
   126  }
   127  
   128  func findProcess(pid int) (p *Process, err error) {
   129  	// NOOP for unix.
   130  	return newProcess(pid, 0), nil
   131  }
   132  
   133  func (p *ProcessState) userTime() time.Duration {
   134  	return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
   135  }
   136  
   137  func (p *ProcessState) systemTime() time.Duration {
   138  	return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
   139  }