I've looked into the Linux kernel source and I was wondering what the kernel sees as a task? Because obviously the CPU runs machine instructions so I thought the scheduler fetches maybe the memory adress of the main function of a program and puts it on the CPU. Is that at least kind of correct? When I click on an executable program, what will actually happen inside the scheduler?
EDIT:
I saw several task-related structs in the source code that stored a bunch of integers and floats (flags, priority etc.)...But I am wondering how the scheduler finds the machine instructions of my programs.
At a minimum a task is a set of register values. One of them is the program counter. When the kernel switches task it stores the current values of all registers in the task structure for the old task. It then loads all the register values from the new task structure, loading the program counter last. This resumes the execution of that task.
Now the hard to understand part is that in most kernels the program counter isn't loaded at all at task switch. Now how can that switch tasks then?
The trick is that all task switching is always done in the same function, which must be written in ASM. So the program counter of the old task is always exactly the program counter of the new task. So it doesn't need to be loaded at all. Execution simply continues where it is. BUT the code now runs in the context of the new task. And when the function returns it returns from where previously the new task called the task switching function. Maybe it's simpler to understand if I say that the new tasks program counter is loaded from the stack when the task switch function returns.
Anyway, what the scheduler does is switch the whole CPU state from one task to the other. It's much more than just a function pointer in C. If you want a C equivalent then look at setjmp() + longjmp().