]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/tests/threads.cc
Initial checkin from Perforce.
[polintos/scott/priv.git] / kernel / tests / threads.cc
1 // tests/threads.cc
2 //
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
4 // 
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 conditions:
11 // 
12 //     * Redistributions of source code must retain the above copyright notice,
13 //       this list of conditions and the following disclaimers.
14 // 
15 //     * Redistributions in binary form must reproduce the above copyright notice,
16 //       this list of conditions and the following disclaimers in the
17 //       documentation and/or other materials provided with the distribution.
18 // 
19 //     * The names of the Software's authors and/or contributors
20 //       may not be used to endorse or promote products derived from
21 //       this Software without specific prior written permission.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
25 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
26 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
29 // SOFTWARE.
30
31 #include <kern/types.h>
32 #include <kern/libc.h>
33 #include <kern/time.h>
34 #include <kern/thread.h>
35
36 void wake(Time::KTimerEntry *entry)
37 {
38         Threads::Blocker *b = static_cast<Threads::Blocker *>(entry->data);
39         b->wake();
40 }
41
42 void clearflag(Time::KTimerEntry *entry)
43 {
44         int *flag = static_cast<int *>(entry->data);
45         *flag = 0;
46 }
47
48 void threadb(void *arg)
49 {
50         Time::KTimerEntry timer(Time::monotonic_timers);
51         Threads::ThreadBlocker tb(curthread);
52         
53         for (;;) {
54                 volatile int flag = 1;
55                 Time::Time now;
56                 Time::monotonic_clock.get_time(&now);
57                 
58                 now.seconds += 2;
59                 
60                 timer.func = clearflag;
61                 timer.data = (void *)(&flag);
62                 timer.arm(now);
63                 
64                 while (flag)
65                         printf("B");
66
67                 now.seconds += 2;
68
69                 tb.blocked = true;
70                 timer.func = wake;
71                 timer.data = &tb;
72                 timer.arm(now);
73                 
74                 curthread->block(&tb);
75         }
76 }
77
78 extern System::Mem::Mappable Mem::physmem;
79
80 void threada(void *arg)
81 {
82         Time::KTimerEntry timer(Time::monotonic_timers);
83         Threads::ThreadBlocker tb(curthread);
84         
85         Threads::sched.new_thread(threadb, NULL, "thread b")->wake();
86
87         for (;;) {
88                 volatile int flag = 1;
89                 Time::Time now;
90                 Time::monotonic_clock.get_time(&now);
91                 
92                 now.seconds++;
93                 
94                 timer.func = clearflag;
95                 timer.data = (void *)(&flag);
96                 timer.arm(now);
97                 
98                 while (flag)
99                         printf("A");
100
101                 now.seconds++;
102
103                 tb.blocked = true;
104                 timer.func = wake;
105                 timer.data = &tb;
106                 timer.arm(now);
107                 
108                 curthread->block(&tb);
109         }
110 }
111
112 void run_test()
113 {
114         Threads::sched.new_thread(threada, NULL, "thread a")->wake();
115 }