Created
November 20, 2020 09:46
-
-
Save Zhang-Siyang/364b512192275fa9d04978353b5d4443 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//go:linkname reflect_makechan reflect.makechan | |
func reflect_makechan(t *chantype, size int) *hchan { | |
return makechan(t, size) | |
} | |
func makechan64(t *chantype, size int64) *hchan { | |
if int64(int(size)) != size { | |
panic(plainError("makechan: size out of range")) | |
} | |
return makechan(t, int(size)) | |
} | |
func makechan(t *chantype, size int) *hchan { | |
elem := t.elem | |
// compiler checks this but be safe. | |
if elem.size >= 1<<16 { | |
throw("makechan: invalid channel element type") | |
} | |
if hchanSize%maxAlign != 0 || elem.align > maxAlign { | |
throw("makechan: bad alignment") | |
} | |
mem, overflow := math.MulUintptr(elem.size, uintptr(size)) | |
if overflow || mem > maxAlloc-hchanSize || size < 0 { | |
panic(plainError("makechan: size out of range")) | |
} | |
// Hchan does not contain pointers interesting for GC when elements stored in buf do not contain pointers. | |
// buf points into the same allocation, elemtype is persistent. | |
// SudoG's are referenced from their owning thread so they can't be collected. | |
// TODO(dvyukov,rlh): Rethink when collector can move allocated objects. | |
var c *hchan | |
switch { | |
case mem == 0: | |
// Queue or element size is zero. | |
c = (*hchan)(mallocgc(hchanSize, nil, true)) | |
// Race detector uses this location for synchronization. | |
c.buf = c.raceaddr() | |
case elem.ptrdata == 0: | |
// Elements do not contain pointers. | |
// Allocate hchan and buf in one call. | |
c = (*hchan)(mallocgc(hchanSize+mem, nil, true)) | |
c.buf = add(unsafe.Pointer(c), hchanSize) | |
default: | |
// Elements contain pointers. | |
c = new(hchan) | |
c.buf = mallocgc(mem, elem, true) | |
} | |
c.elemsize = uint16(elem.size) | |
c.elemtype = elem | |
c.dataqsiz = uint(size) | |
if debugChan { | |
print("makechan: chan=", c, "; elemsize=", elem.size, "; dataqsiz=", size, "\n") | |
} | |
return c | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment