r/compsci • • 2d ago

what is context switching?

I know this has been discussed before, but it's extremely confusing for me because of how many variations there are in definitions. Here are some observations:

  1. Most people would agree that process-switches and system calls both involve context switching, however I think the underlying "state saving" is different between these two events. In a system call, there is an entry phase where the kernel saves register state to the kernel stack (and not every system call leads to a process or thread switch). In a process-switch, the PCB gets updated so that the process can later be resumed. Is this accurate?

  2. On Linux, both processes and threads are schedule-able (they're both "tasks"). As best as I can understand, there's a function called context_switch() in the Linux kernel that gets called during scheduling. However, it seems context switching is used in a broader sense. In other words "context switching" doesn't mean exactly that we're calling the function "context_switch()".

  3. There is at least one textbook that considers functions as having their own context (Doeppner's Operating Systems in Depth). This is a little confusing because I can't find anyone else who considers a function call a change in context.

The question is: does anyone have a technical definition of context switching that captures what most people mean when they say "context switch"?

I've also been reading about the xv6 since it's a smaller educational operating system. If somebody has experience/knowledge of the xv6 internals, I would appreciate any input. Thank you

1 Upvotes

18 comments sorted by

13

u/SomewhereRude2144 2d ago

The thing that helped me was stopping to think of it as one specific mechanism and more as "whatever state you need to save and restore when you hand the CPU to something else." That's why a syscall and a full process switch both count, but they save different amounts. The function call thing is where it gets fuzzy, because most of the time the compiler handles that saving via the calling convention and nobody calls it a context switch. But conceptually, yeah, you're switching the active context, it's just not the OS doing it.

0

u/Mossack-Fonseca 2d ago edited 2d ago

I guess another area where there's disagreement seems to be with user-level threads. Do user-level threads require context switching? They're usually described as having a thread control block. However I can find a few resources online saying they don't. For example:

https://lass.cs.umass.edu/~shenoy/courses/fall08/lectures/Lec06.pdf

There is no context switch involved when switching threads.

User-level threads do not require system calls to create them or context switches to move between them

Am I misunderstanding this?

7

u/KarlSethMoran 2d ago

I'd go with "threads employ a very light-weight context switch, much less expensive than a process context switch".

How light it is depends very much on the design of the OS.

1

u/nicuramar 2d ago

That’s true if the switch is to another thread in the same process, but this isn’t generally true.

3

u/KarlSethMoran 2d ago

Well, otherwise you're switching processes, so.

1

u/nicuramar 2d ago

Yes, but you’re also switching threads. Because a thread is what a CPU core is executing, at any given time. A process has at least one thread.

3

u/nemotux 2d ago

I think you're getting hung up on trying to assign a specific, technical meaning to a term that is used frequently in rather broad, general terms.

A function call is a context switch. It's just not an expensive context switch handled by the OS.

People use the term very loosely in a lot of different situations. For example, my coworkers will often refer to abruptly shifting from one topic to another in a conversation as a context switch.

It's not that there's disagreement about the term's meaning. It's that English is imprecise and a term's meaning may switch from one context to another.

2

u/Mossack-Fonseca 2d ago edited 2d ago

I think you're getting hung up on trying to assign a specific, technical meaning to a term that is used frequently in rather broad, general terms.

Yea that's true. I'm just very unsatisfied with the answer "the term context depends on context" (I tried to ask on one of the stack exchanges and that's the answer I received)

A function call is a context switch. It's just not an expensive context switch handled by the OS.

The issue I have with this is that there are function calling conventions, eg System V ABI. So there are exact rules that are followed when performing a function call (depending on OS). There isn't a phase where several/all registers are blindly saved to a stack. But if you look at interrupt handling code, for instance, that's exactly what it does. I think that is a material difference. That makes me think that the term is way too broad.

4

u/nemotux 2d ago

Sure there's a material difference between the two. They have different constraints. In both cases, though, the originating context gets restored sufficiently for the originating context to resume.

The function call case is just specialized to streamline how much context actually needs to be saved/restored. That's an optimization. But it's still a context switch.

Don't get too twisted up in specific language definitions. English changes all the time. What's more important is to recognize when confusion might arise and to couch your language in sufficient context so meaning is communicated. Specific words are just syntax to convey meaning. It's the meaning that's actually important.

1

u/Mclarenf1905 2d ago

The question is: does anyone have a technical definition of context switching that captures what most people mean when they say "context switch"?

That makes me think that the term is way too broad.

You literally asked for a broad definition of the term. I honestly have no idea what you are after here. Its a broad imprecise term that is context/domain dependent in nature. The term is used so broadly it would be impossible to come up with a precise definition that clearly covered all possible uses cases with any degree of precision.

0

u/Mossack-Fonseca 2d ago edited 2d ago

I'm asking for a technical definition that somebody can use to decide what is and isn't a context switch. "it depends" doesn't do it for me. And that doesn't mean the definition has to necessarily accommodate everything under the sun. Some people consider a function call to be an example of a context switch. I've seen at least one author explicitly exclude that case. Surely you can appreciate that there might be a reason for that? I don't understand the dismissiveness here.

1

u/nemotux 2d ago

Yeah, and what we're saying (and what you seem to be refusing to accept) is that what you're asking for doesn't exist. It may have existed historically some time back when we were first inventing multi-tasking OSs. But that ship sailed a long time ago.

Whether it does it for you or not, "it depends" is the only answer today. It depends on the particular situation it's being used in. It also depends on the author/speaker using it: what they're trying to convey and their own linguistic background. You may find two authors using "context switch" seemingly with conflicting definitions because those two authors independently experienced hearing the word used differently in their own different educational/professional backgrounds.

There's also how the reader interprets it.

In the example you quoted above about a function call not having an expensive context switch, I would have interpreted that not as function calls not including context switches, but as function calls not including expensive context switches. Emphasis on the "expensive". There is still a "cheap" context switch going on.

1

u/Mossack-Fonseca 2d ago edited 2d ago

In the example you quoted above about a function call not having an expensive context switch, I would have interpreted that not as function calls not including context switches, but as function calls not including expensive context switches. Emphasis on the "expensive". There is still a "cheap" context switch going on.

You're right. There was a different way to interpret the quote I provided, which is why I posted a second link with a more definitive statement (see page 5). I posted the links as I found them. But again, there has to be some level of openness to have that conversation. I'm sensing a lot of resistance here.

And what I said about function calls is not related to the quote I provided further up in the conversation chain. The quote I provided above was about user-level threads. I updated the initial post where I provided the quote to make it clearer to everyone else. Jumping back to function calls, yes, there is an author who very explicitly excludes function calls.

1

u/nemotux 2d ago

Oh yes. Sorry, I probably failed to go back and reread after context switching this back in. But I think the point still holds. Reader interpretation is part of the story.

I read the resistance as double-edged. People keep giving you the "it depends" answer, but you're also refusing to accept that answer.

If it helps, I see the following analogy with your question: consider the definition of "soup". How much liquid is necessary for a bowl of something to be called "soup" rather than, say, "stew"? Ask 10 people where exactly that boundary is, and you'll get 10 different answers.

Same goes with how much context saving and restoring is necessary before something should be considered a "context switch" vs. something else. There's no one answer because the term is too diluted by past broad hand-wavy usage.

1

u/Benabik 2d ago

A process switch requires a kernel call, caused by a timer interrupt instead of a syscall. The kernel basically just switches its pointers for what state it will restore afterwards. So there is little difference between the two. (Although a syscall can also result in a process switch if it blocks.) I do not recall the exact mechanisms in the Linux kernel.

Kernel threads (pthreads on posix) are the same thing, with the slight exception that the kernel does not need to change the memory map, but most of the differences are just that the thread shares many data structures in the kernel with the rest of the process. There are library-only thread solutions (green threads or async tasks) that the kernel is unaware of. In those cases the library does basically the same thing, but it can be faster without the protection mode change. The tradeoff is that all green threads block if a system call blocks.

1

u/kazprog 2d ago edited 2d ago

A function call's context is more often called its "frame" in the callstack. There are registers in x86 specifically for pointing to the bottom of the frame and the current top of the frame, which would also align with the top of the callstack as a whole. I think they are called rbp (register base pointer) and rsp (register stack pointer). Calling that a "context" formally is a bit strange, but it might make sense informally if you're trying to discuss lexical scope and what syntactic bindings are available and how it relates to a calling convention.

A timer-based pre-emptive process switch runs like this:

  • an interrupt fires from the interrupt controller's timer, the PIC or APIC or something even more new
  • the interrupt mechanism runs a context switch from the user process to the kernel scheduler:
  • the cpu core that is running the process has its state saved to a register-file or to the top of the stack, saving all of the normal registers and importantly the instruction pointer, spelled "rip", humorously enough.
  • the kernel's interrupt handling routine runs as a result of the same interrupt mechanism, but only after the core's state was saved
  • the kernel's interrupt handler runs the scheduler in this case, and the scheduler somehow knows what the prior task was, how long it was given to run a task, who else is waiting to run (the "run-queue") and the relative priorities of all of these tasks, and it runs the task it thinks is best suited to running next. in order to not thrash too much, usually processes are given a certain amount of time to run without being switched away from, this is called the scheduler's "quantum", or just "a quantum".
  • the scheduler context switches back to the process that has been selected.

so there are two context switches, one invoked by the PIC (programmable interrupt controller), the other invoked by the scheduler itself, once it has decided who next should go.

A context switch has two parts, highlighted above:

  • save the state from the prior process, either in a registerfile or on top of the stack
  • pick up the instruction pointer and the rest of the state from the next process, and begin executing.
  • in the ones i've seen, the context switch often pushes the instruction pointer onto the stack and then does something a bit tricky, with the return instruction or a call instruction or something, to invoke into the next process.

A kernel system call, on the other hand, runs like so:

  • the process cooperatively (rather than pre-emptively) calls the system call, running a context switch, storing the user process' state and loading the kernel's state.
  • the core escalated execution permissions from the user ring to the kernel ring
  • the kernel figures out what system call to run
  • the kernel runs it, either copying the necessary results to a memory address the user has provided, by modifying the process table itself (opening a file), or just through its return value
  • the kernel cooperatively context switches back, de-escalating permissions and return control to the user.

1

u/DawnOnTheEdge 2d ago

It seems to primarily mean a switch between user and kernel mode (on a hardware level, between highest privilege with access to all memory on the system and lowest privilege with access only to the process’ address space).

1

u/gunni 2d ago

I just happened to see a video about that exact topic recently.