ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/evthread.C
Revision: 1.7
Committed: Thu Nov 20 12:18:07 2008 UTC (15 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_72, rel-2_73, rel-2_76, rel-2_77, rel-2_74, rel-2_75, rel-2_78
Changes since 1.6: +4 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 *
6 * Deliantra is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * The authors can be reached via e-mail to <support@deliantra.net>
20 */
21
22 #include "global.h"
23 #include "evthread.h"
24 #include "cfperl.h"
25
26 thread evthread;
27 static ev_loop *loop;
28
29 #define TICK_CYCLES 4
30
31 // the tick watcher is activated every TICK_CYCLES
32 ev_async tick_watcher;
33 EV_ATOMIC_T coroapi::cede_pending;
34
35 // the ticker runs TICK_CYCLES times as fast as the main server tick
36 static ev_periodic cede_watcher;
37
38 /////////////////////////////////////////////////////////////////////////////
39
40 // it is a bit silly to have to use a mutex, but contention
41 // is basically non-existant, favouring good mutex implementations.
42 static SMUTEX (evthread_mutex);
43 static NV next_tick;
44
45 NV get_next_tick ()
46 {
47 SMUTEX_LOCK (evthread_mutex);
48 NV retval = next_tick;
49 SMUTEX_UNLOCK (evthread_mutex);
50 return retval;
51 }
52
53 static void
54 cede_cb (EV_P_ ev_periodic *w, int revents)
55 {
56 static int cycle = 0;
57
58 if (++cycle == TICK_CYCLES)
59 {
60 cycle = 0;
61
62 SMUTEX_LOCK (evthread_mutex);
63 next_tick = w->at + TICK / TICK_CYCLES * (TICK_CYCLES - 1);
64 SMUTEX_UNLOCK (evthread_mutex);
65
66 ev_async_send (EV_DEFAULT_UC, &tick_watcher);
67 }
68
69 coroapi::cede_pending = 1;
70 }
71
72 static void
73 tick_cb (EV_P_ ev_async *w, int revents)
74 {
75 cfperl_tick ();
76 }
77
78 /////////////////////////////////////////////////////////////////////////////
79
80 static ev_async async_watcher;
81 static ev_io aio1_watcher;
82 static ev_idle aio2_watcher;
83 static EV_ATOMIC_T aio_pending;
84
85 static void
86 aio2_cb (EV_P_ ev_idle *w, int revents)
87 {
88 IV reqs;
89
90 CALL_BEGIN (0);
91 CALL_CALL ("IO::AIO::poll_cb", G_SCALAR);
92
93 reqs = POPi;
94 if (count > 0 && reqs < 0)
95 ev_idle_start (EV_A, w);
96 else
97 ev_idle_stop (EV_A, w);
98
99 CALL_END;
100 }
101
102 static void
103 async_cb (EV_P_ ev_async *w, int revents)
104 {
105 aio2_cb (EV_A, &aio2_watcher, 0);
106 }
107
108 static void
109 aio1_cb (EV_P_ ev_io *w, int revents)
110 {
111 char dummy;
112
113 if (read (w->fd, &dummy, 1) > 0)
114 {
115 ev_async_send (EV_DEFAULT_UC, &async_watcher);
116 coroapi::cede_pending = 1;
117 }
118 }
119
120 /////////////////////////////////////////////////////////////////////////////
121
122 static void *
123 evthread_proc (void *arg)
124 {
125 ev_loop (loop, 0);
126
127 return 0;
128 }
129
130 void evthread_start (int aiofd)
131 {
132 I_EV_API ("evthread");
133
134 // main loop
135 ev_async_init (&tick_watcher, tick_cb);
136 ev_set_priority (&tick_watcher, 1);
137 ev_async_start (EV_DEFAULT_UC, &tick_watcher);
138
139 ev_async_init (&async_watcher, async_cb);
140 ev_set_priority (&async_watcher, 1);
141 ev_async_start (EV_DEFAULT_UC, &async_watcher);
142
143 ev_idle_init (&aio2_watcher, aio2_cb);
144
145 // secondary loop
146 loop = ev_loop_new (0);
147
148 ev_periodic_init (&cede_watcher, cede_cb, 0, TICK / TICK_CYCLES, 0);
149 ev_periodic_start (loop, &cede_watcher);
150
151 ev_io_init (&aio1_watcher, aio1_cb, aiofd, EV_READ);
152 ev_io_start (loop, &aio1_watcher);
153
154 evthread.start (evthread_proc);
155 }
156
157
158