ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/evthread.C
Revision: 1.1
Committed: Wed Apr 2 11:13:57 2008 UTC (16 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
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 5
30
31 // the ticker runs TICK_CYCLES times as fast as the main server tick
32 static ev_periodic cede_watcher;
33 // the tick watcher is activated every TICK_CYCLES
34 ev_async tick_watcher;
35
36 EV_ATOMIC_T coroapi::cede_pending;
37
38 // it is a bit silly to have to use a mutex, but contention
39 // is basically non-existant, favouring good mutex implementations.
40 static SMUTEX (evthread_mutex);
41 static NV next_tick;
42
43 NV get_next_tick ()
44 {
45 SMUTEX_LOCK (evthread_mutex);
46 NV retval = next_tick;
47 SMUTEX_UNLOCK (evthread_mutex);
48 return retval;
49 }
50
51 static void
52 cede_cb (EV_P_ ev_periodic *w, int revents)
53 {
54 static int cycle = 0;
55
56 if (++cycle == TICK_CYCLES)
57 {
58 cycle = 0;
59
60 SMUTEX_LOCK (evthread_mutex);
61 next_tick = w->at + TICK / TICK_CYCLES * (TICK_CYCLES - 1);
62 SMUTEX_UNLOCK (evthread_mutex);
63
64 ev_async_send (EV_DEFAULT, &tick_watcher);
65 }
66
67 coroapi::cede_pending = 1;
68 }
69
70 static void
71 tick_cb (EV_P_ ev_async *w, int revents)
72 {
73 cfperl_tick ();
74 }
75
76 static void *
77 evthread_proc (void *arg)
78 {
79 loop = ev_loop_new (0);
80
81 ev_async_init (&tick_watcher, tick_cb);
82 ev_set_priority (&tick_watcher, 1);
83 ev_async_start (EV_DEFAULT, &tick_watcher);
84
85 ev_periodic_init (&cede_watcher, cede_cb, 0, TICK / TICK_CYCLES, 0);
86 ev_periodic_start (loop, &cede_watcher);
87
88 ev_loop (loop, 0);
89
90 return 0;
91 }
92
93 void evthread_start ()
94 {
95 I_EV_API ("evthread");
96 evthread.start (evthread_proc);
97 }
98
99
100