ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/evthread.C
Revision: 1.10
Committed: Tue Nov 3 23:44:21 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_90, rel-2_92, rel-2_93
Changes since 1.9: +1 -1 lines
Log Message:
tighten copyright statements for files containing no gpl code whatsoever anymore

File Contents

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