Is the Unix process scheduler itself a process, or does it piggyback on other processes in the same way a system call does (running kernel code in the user process with the kernel bit set)?
A Unix process scheduler doesn't really "piggy back" on a system call. Executing the scheduler is part of just about any system call.
read() system call or an
exit() system call absolutely has to cause the scheduler to execute. In the case of a
read() a disk access might take a very long time. Unless you want everything to be very slow, you need to run the scheduler to see what process should run while the first process waits for the disk to come back with data. A
read() might happen on a socket - the time it takes for data to come back from some remote server is indeterminate. The kernel must reschedule some other process. In the case of an
exit(), the process making the system call doesn't want to exist any more, so some other process must be scheduled. For a
pause() or an
alarm(), the process wants to execute some time in the future. Again, the scheduler has to pick another process to run.
I believe that most, but not all, system calls cause the Unix/Linux/*BSD scheduler to execute. Sometimes
gettimeofday() doesn't cause the scheduler to run - Solaris used to work that way. But in general, you can safely think of a system call as doing the work (sending data over the NIC, setting up for a disk read or write, doing process exit work, forking, whatever), running the scheduler, and then executing whatever process is supposed to run next. Sometimes that's the same process the made the system call, but a lot of the time, it's not.