type profBuf … type profAtomic … type profIndex … const profReaderSleeping … const profWriteExtra … func (x *profAtomic) load() profIndex { … } func (x *profAtomic) store(new profIndex) { … } func (x *profAtomic) cas(old, new profIndex) bool { … } func (x profIndex) dataCount() uint32 { … } func (x profIndex) tagCount() uint32 { … } // countSub subtracts two counts obtained from profIndex.dataCount or profIndex.tagCount, // assuming that they are no more than 2^29 apart (guaranteed since they are never more than // len(data) or len(tags) apart, respectively). // tagCount wraps at 2^30, while dataCount wraps at 2^32. // This function works for both. func countSub(x, y uint32) int { … } // addCountsAndClearFlags returns the packed form of "x + (data, tag) - all flags". func (x profIndex) addCountsAndClearFlags(data, tag int) profIndex { … } // hasOverflow reports whether b has any overflow records pending. func (b *profBuf) hasOverflow() bool { … } // takeOverflow consumes the pending overflow records, returning the overflow count // and the time of the first overflow. // When called by the reader, it is racing against incrementOverflow. func (b *profBuf) takeOverflow() (count uint32, time uint64) { … } // incrementOverflow records a single overflow at time now. // It is racing against a possible takeOverflow in the reader. func (b *profBuf) incrementOverflow(now int64) { … } // newProfBuf returns a new profiling buffer with room for // a header of hdrsize words and a buffer of at least bufwords words. func newProfBuf(hdrsize, bufwords, tags int) *profBuf { … } // canWriteRecord reports whether the buffer has room // for a single contiguous record with a stack of length nstk. func (b *profBuf) canWriteRecord(nstk int) bool { … } // canWriteTwoRecords reports whether the buffer has room // for two records with stack lengths nstk1, nstk2, in that order. // Each record must be contiguous on its own, but the two // records need not be contiguous (one can be at the end of the buffer // and the other can wrap around and start at the beginning of the buffer). func (b *profBuf) canWriteTwoRecords(nstk1, nstk2 int) bool { … } // write writes an entry to the profiling buffer b. // The entry begins with a fixed hdr, which must have // length b.hdrsize, followed by a variable-sized stack // and a single tag pointer *tagPtr (or nil if tagPtr is nil). // No write barriers allowed because this might be called from a signal handler. func (b *profBuf) write(tagPtr *unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) { … } // close signals that there will be no more writes on the buffer. // Once all the data has been read from the buffer, reads will return eof=true. func (b *profBuf) close() { … } // wakeupExtra must be called after setting one of the "extra" // atomic fields b.overflow or b.eof. // It records the change in b.w and wakes up the reader if needed. func (b *profBuf) wakeupExtra() { … } type profBufReadMode … const profBufBlocking … const profBufNonBlocking … var overflowTag … func (b *profBuf) read(mode profBufReadMode) (data []uint64, tags []unsafe.Pointer, eof bool) { … }