This is a very good question, for which I did not find an official statement on the fly, except for the code. I would be happy for any hint of official documentation.
The answer is no, cgo calls do not block the scheduler .
For future reference, it is useful to know that inside Go uses G for goroutines, M for machines (threads) and P for proccessor. Gorut run on processors running on machines.
The function call C from G works in accordance with the code documentation :
// To call into the C function f from Go, the cgo-generated code calls // runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a // gcc-compiled function written by cgo. // // runtime.cgocall (below) locks g to m, calls entersyscall // so as not to block other goroutines or the garbage collector, // and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame). // // runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack // (assumed to be an operating system-allocated stack, so safe to run // gcc-compiled code on) and calls _cgo_Cfunc_f(frame). // // _cgo_Cfunc_f invokes the actual C function f with arguments // taken from the frame structure, records the results in the frame, // and returns to runtime.asmcgocall. // // After it regains control, runtime.asmcgocall switches back to the // original g (m->curg) stack and returns to runtime.cgocall. // // After it regains control, runtime.cgocall calls exitsyscall, which blocks // until this m can run Go code without violating the $GOMAXPROCS limit, // and then unlocks g from m.
entersyscall essentially says that the runtime of this goroutine is now under "external" control, as in the situation when we do syscalls for the kernel. Another probably useful bit is that blocking g to m (blocking the call to ggooutine cgo for an OS thread) allows the runtime to allocate a new OS thread (theoretically exceeding GOMAXPROCS ).
source share