1 // core/thread.cc -- Scheduler and thread creation/destruction
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal with
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 // of the Software, and to permit persons to whom the Software is furnished to do
10 // so, subject to the following condition:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
23 #include <util/lock.h>
24 #include <kern/thread.h>
27 // OPT: add inline, lockless uncontended case
29 // FIXME: Allow a high-priority blocker to steal a lock from
30 // a low-priority holder if the holder has not yet run. This
31 // prevents rescheduling every iteration if both threads are
32 // repeatedly acquiring and releasing the lock.
36 DroppableAutoSpinLockRecIRQ autolock(spinlock);
39 lockval = reinterpret_cast<ulong>(curthread);
43 assert(lockval != reinterpret_cast<ulong>(curthread));
45 Threads::ThreadBlocker blocker(curthread);
46 waitqueue.block(&blocker);
49 lockval = reinterpret_cast<ulong>(curthread);
50 waitqueue.unblock(&blocker);
55 curthread->block(&blocker);
57 // FIXME: interruptible locks
58 assert(lockval == reinterpret_cast<ulong>(curthread));
63 AutoSpinLockRecIRQ autolock(spinlock);
64 assert(lockval == reinterpret_cast<ulong>(curthread));
66 if (waitqueue.empty()) {
71 Threads::Blocker *b = waitqueue.unblock_one();
72 lockval = reinterpret_cast<ulong>(b->thread);