Threads and fibers and not mutually exclusive and there are several implementation today of fibers in various libraries. The D language implements fibers in their standard library and is entirely a user space creation. What is needed is some kind user space task switcher which of course will be architecture dependent. Fibers exist in other languages as well.
My OS has kernel threads and user space threads, these two are completely disjoint. One drawback with user threads is that preemption between threads in the same process becomes more difficult so time slicing is not that simple. It isn't impossible though but requires more complexity. Still yielding a user space thread is simple. My OS does not have user thread time slicing and I haven't so far seen any use for it and the system is built on short lived user space threads.
If you are interested in this subject first place to read is Scheduler Activations:
https://en.wikipedia.org/wiki/Scheduler_activationshttps://web.eecs.umich.edu/~mosharaf/Re ... ations.pdfAlso interesting is MS user mode scheduling, dive further in there in order to see how they have solved it.
https://docs.microsoft.com/en-us/window ... schedulingThere is one misconception about user mode scheduling that it is faster than a kernel thread only system, this is not the case and user mode scheduling does not really reduce the number of kernel API calls that it matters. This is one of the reasons the scheduler activation solution was not becoming popular in Free BSD.