// Put adds x to the pool. func (p *Pool) Put(x interface{}) { if x == nil { return } if race.Enabled { if fastrand()%4 == 0 { // Randomly drop x on floor. return } race.ReleaseMerge(poolRaceAddr(x)) race.Disable() } l := p.pin() if l.private == nil { l.private = x x = nil } runtime_procUnpin() if x != nil { l.Lock() l.shared = append(l.shared, x) l.Unlock() } if race.Enabled { race.Enable() } }
func Write(fd int, p []byte) (n int, err error) { if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } n, err = write(fd, p) if race.Enabled && n > 0 { race.ReadRange(unsafe.Pointer(&p[0]), n) } if msanenabled && n > 0 { msanRead(unsafe.Pointer(&p[0]), n) } return }
//sys sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error) //sendfile64(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } var soff Offset_t var psoff *Offset_t if offset != nil { soff = Offset_t(*offset) psoff = &soff } written, err = sendfile(outfd, infd, psoff, count) if offset != nil { *offset = int64(soff) } return }
func Write(fd Handle, p []byte) (n int, err error) { if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } var done uint32 e := WriteFile(fd, p, &done, nil) if e != nil { return 0, e } if race.Enabled && done > 0 { race.ReadRange(unsafe.Pointer(&p[0]), int(done)) } if msanenabled && done > 0 { msanRead(unsafe.Pointer(&p[0]), int(done)) } return int(done), nil }
// Add 添加 delta,对于 WaitGroup 的 counter 来说,它可能为负数。 // 若 counter 变为零,在 Wait() 被释放后所有Go程就会阻塞。 // 若 counter 变为负数,Add 就会引发Panic。 // // 注意,当 counter 为零时,用正整数的 delta 调用它必须发生在调用 Wait 之前。 // 用负整数的 delta 调用它,或在 counter 大于零时开始用正整数的 delta 调用它, // 那么它可以在任何时候发生。 // 一般来说,这意味着对 Add 的调用应当在该语句创建Go程,或等待其它事件之前执行。 // 具体见 WaitGroup 的示例。 func (wg *WaitGroup) Add(delta int) { statep := wg.state() if race.Enabled { _ = *statep // trigger nil deref early if delta < 0 { // Synchronize decrements with Wait. race.ReleaseMerge(unsafe.Pointer(wg)) } race.Disable() defer race.Enable() } state := atomic.AddUint64(statep, uint64(delta)<<32) v := int32(state >> 32) w := uint32(state) if race.Enabled { if delta > 0 && v == int32(delta) { // The first increment must be synchronized with Wait. // Need to model this as a read, because there can be // several concurrent wg.counter transitions from 0. race.Read(unsafe.Pointer(&wg.sema)) } } if v < 0 { panic("sync: negative WaitGroup counter") } if w != 0 && delta > 0 && v == int32(delta) { panic("sync: WaitGroup misuse: Add called concurrently with Wait") } if v > 0 || w == 0 { return } // This goroutine has set counter to 0 when waiters > 0. // Now there can't be concurrent mutations of state: // - Adds must not happen concurrently with Wait, // - Wait does not increment waiters if it sees counter == 0. // Still do a cheap sanity check to detect WaitGroup misuse. if *statep != state { panic("sync: WaitGroup misuse: Add called concurrently with Wait") } // Reset waiters count to 0. *statep = 0 for ; w != 0; w-- { runtime_Semrelease(&wg.sema) } }
func (fd *netFD) Write(buf []byte) (int, error) { if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } o := &fd.wop o.InitBuf(buf) n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error { return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) }) if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("wsasend", err) } return n, err }
// RUnlock undoes a single RLock call; // it does not affect other simultaneous readers. // It is a run-time error if rw is not locked for reading // on entry to RUnlock. func (rw *RWMutex) RUnlock() { if race.Enabled { _ = rw.w.state race.ReleaseMerge(unsafe.Pointer(&rw.writerSem)) race.Disable() } if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 { if r+1 == 0 || r+1 == -rwmutexMaxReaders { race.Enable() panic("sync: RUnlock of unlocked RWMutex") } // A writer is pending. if atomic.AddInt32(&rw.readerWait, -1) == 0 { // The last reader unblocks the writer. runtime_Semrelease(&rw.writerSem) } } if race.Enabled { race.Enable() } }
func (fd *netFD) writeBuffers(buf *Buffers) (int64, error) { if len(*buf) == 0 { return 0, nil } if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } o := &fd.wop o.InitBufs(buf) n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error { return syscall.WSASend(o.fd.sysfd, &o.bufs[0], uint32(len(*buf)), &o.qty, 0, &o.o, nil) }) o.ClearBufs() if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("wsasend", err) } testHookDidWritev(n) buf.consume(int64(n)) return int64(n), err }
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } return sendfile(outfd, infd, offset, count) }