ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/evthread.C
Revision: 1.2
Committed: Wed Apr 2 12:39:06 2008 UTC (16 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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 root 1.2 #define TICK_CYCLES 4
30 root 1.1
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