4 Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
27 #include "sim_cycle_timers.h"
30 #define DEBUG(__w) __w
31 #define DUMP(_pool,_w) { \
32 printf("%s:%d %s ",__func__,__LINE__, _w);\
33 for (int _i=0;_i<_pool->count;_i++) \
34 printf("[%2d:%7d] ",_i,(int)_pool->timer[_i].when);\
39 #define DUMP(_pool,_w)
43 avr_cycle_timer_reset(
46 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
47 memset(pool, 0, sizeof(*pool));
50 // no sanity checks checking here, on purpose
52 avr_cycle_timer_insert(
54 avr_cycle_count_t when,
55 avr_cycle_timer_t timer,
58 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
62 // find it's place int the list
64 while (inserti < pool->count && pool->timer[inserti].when > when)
67 int cnt = pool->count - inserti;
69 memmove(&pool->timer[inserti + 1], &pool->timer[inserti],
70 cnt * sizeof(avr_cycle_timer_slot_t));
73 pool->timer[inserti].timer = timer;
74 pool->timer[inserti].param = param;
75 pool->timer[inserti].when = when;
76 DEBUG(printf("%s %2d/%2d when %7d %p/%p\n", __func__, inserti, pool->count, (int)(when - avr->cycle), timer, param);)
81 avr_cycle_timer_register(
83 avr_cycle_count_t when,
84 avr_cycle_timer_t timer,
87 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
89 // remove it if it was already scheduled
90 avr_cycle_timer_cancel(avr, timer, param);
92 if (pool->count == MAX_CYCLE_TIMERS) {
93 fprintf(stderr, "%s: pool is full (%d)!\n", __func__, MAX_CYCLE_TIMERS);
96 avr_cycle_timer_insert(avr, when, timer, param);
100 avr_cycle_timer_register_usec(
103 avr_cycle_timer_t timer,
106 avr_cycle_timer_register(avr, avr_usec_to_cycles(avr, when), timer, param);
110 avr_cycle_timer_cancel(
112 avr_cycle_timer_t timer,
115 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
117 for (int i = 0; i < pool->count; i++)
118 if (pool->timer[i].timer == timer && pool->timer[i].param == param) {
119 int cnt = pool->count - i - 1;
120 DEBUG(printf("%s %2d when %7d %p/%p\n", __func__, i, (int)(pool->timer[i].when - avr->cycle), timer, param);)
122 memmove(&pool->timer[i], &pool->timer[i+1],
123 cnt * sizeof(avr_cycle_timer_slot_t));
131 * Check to see if a timer is present, if so, return the number (+1) of
132 * cycles left for it to fire, and if not present, return zero
135 avr_cycle_timer_status(
137 avr_cycle_timer_t timer,
140 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
142 for (int i = 0; i < pool->count; i++)
143 if (pool->timer[i].timer == timer && pool->timer[i].param == param) {
144 return 1 + (pool->timer[i].when - avr->cycle);
151 * run thru all the timers, call the ones that needs it,
152 * clear the ones that wants it, and calculate the next
153 * potential cycle we could sleep for...
156 avr_cycle_timer_process(
159 avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
162 return (avr_cycle_count_t)1000;
165 // copy it, since the array is volatile
166 avr_cycle_timer_slot_t timer = pool->timer[pool->count-1];
167 avr_cycle_count_t when = timer.when;
168 if (when > avr->cycle)
169 return when - avr->cycle;
170 pool->count--; // remove the top element now
172 DEBUG(printf("%s %2d when %7d %p/%p\n", __func__, pool->count, (int)(when), timer.timer, timer.param););
173 when = timer.timer(avr, when, timer.param);
174 } while (when && when <= avr->cycle);
176 DEBUG(printf("%s %2d reschedule when %7d %p/%p\n", __func__, pool->count, (int)(when), timer.timer, timer.param);)
177 avr_cycle_timer_insert(avr, when - avr->cycle, timer.timer, timer.param);
179 } while (pool->count);
181 return (avr_cycle_count_t)1000;