As per the functionality of getchar(), it needs to be blocked when the stdio stream buffer is empty. How is this blocking functionality implemented?
And it is said that getchar/getc can be implemented as macros (direct assembly) for performance reasons, how blocking functionality is ensured in this case.
Blocking is in charge of OS kernel. If the operation cannot be realized, then the kernel put the process in a waiting queue which makes it non eligible until the corresponding event (at least a char is available for input) is detected.
implemented as macro has nothing special to do with blocking. This just means that it is not a function and you can't then get the address of it. Note macro doesn't mean direct assembly, it means C macro something like:
#define getchar(void) fgetc(stdin)