Brendan wrote:
If your sister/daughter/spouse/whatever wanted to try smoking crack and didn't know that it's a bad idea; would you say nothing and laugh while they become a crack addict; or would you try to explain that crack has some disadvantages so that they can make an informed decision?
Smoking crack is objectively harmful to the person doing it. OS development (no matter how you do it) is not. In fact, even if you don't get very far or end up giving up on a flawed design, it's generally beneficial; you learn new things, get a better understanding of how other OSs work, etc.
There's absolutely nothing wrong with giving an opinion. Saying "I don't think that's a very good design because..." or "I went with this alternative because..." is fine, good and helpful. However, describing a different idea as "a worthless joke", "pointless", "wrong", etc. isn't at all helpful.
Personally, I would strongly encourage anyone building an OS incorporating new/different ideas. There are plenty of UNIX clones out there (not that building a UNIX clone isn't a major achievement and to be congratulated or that you can't innovate within the confines of "UNIX-like"). Oh, and BTW, UNIX systems traditionally did not allow multiple kernel-level threads per process... That feature didn't begin to appear until around 1990. There's a reason why POSIX.1c allows threads to be entirely user-space. The GNU Portable Threads library is a POSIX.1c-complaint user-level threading library.
Now on to the issue at hand...
Different methods of implementing threads are complex and each have their pros and cons (whether or not you can accept that ways different from yours could possible also be "right").
There are many papers on the subject. User-level threads have the advantage of cheap context switches. Your observation that you could "just have one thread instead" is exactly right. Ultimately, a computer can really only execute one program per CPU core, anything more than that is simply a simulation. The kernel simulates having one CPU core per processes/"kernel thread" and a user-space scheduler than extend this to simulating one CPU core per user-space thread. So, from the kernel's POV you
do "just have one thread" just as from the CPU's POV the entire system is "just one thread". Threads/processes are just an abstraction for the programmer.
Processes "lying" to the kernel is possible on any system that lets processes set their own priority. Where it matters (e.g. on a multi-user system) there are usually security measures the mitigate the impact of this (e.g. only specially-privileged users can set priority above a certain level).
I'm still not sure why you'd need to change a process's priority regularly. Why would you have two threads of wildly differing priority in the same process in the first place?
Of course, the big disadvantage to using purely user-level threading is the inability to take advantage of multiple CPUs/cores. However, it's entirely possible (and common) to have
both user-level and kernel-level threads available on the same system. This then allows you to choose on a per-thread basis. If you've got two threads that are closely working together (e.g. a producer and consumer) where it's rare that both are simultaneously runnable it can make sense for them to share a single kernel-level thread so that switching between them is fast. In this case, you're effectively using user-level threads to implement coroutines (and if your user-level scheduler is non-preemptive, that's exactly what you've got). If you have multiple threads that are often simultaneously runnable and don't share much data, then having them on separate kernel threads so that they can use different CPU cores, if available.
The world of OS development isn't black-and-white. Trying new/different ideas is a good thing; even if they don't ultimately work out, you've learned something.