Subversion Repositories HelenOS

Rev

Rev 2450 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2450 Rev 2461
Line 54... Line 54...
54
#include <proc/thread.h>
54
#include <proc/thread.h>
55
#include <sysinfo/sysinfo.h>
55
#include <sysinfo/sysinfo.h>
56
#include <arch/barrier.h>
56
#include <arch/barrier.h>
57
#include <mm/frame.h>
57
#include <mm/frame.h>
58
#include <ddi/ddi.h>
58
#include <ddi/ddi.h>
59
#if defined CONFIG_TIMEOUT_AVL_TREE || defined CONFIG_TIMEOUT_EXTAVL_TREE
-
 
60
#include <arch/asm.h>
-
 
61
#include <arch/types.h>
-
 
62
#include <panic.h>
-
 
-
 
59
 
63
#endif
60
 
64
/* Pointer to variable with uptime */
61
/* Pointer to variable with uptime */
65
uptime_t *uptime;
62
uptime_t *uptime;
66
 
63
 
67
/** Physical memory area of the real time clock */
64
/** Physical memory area of the real time clock */
68
static parea_t clock_parea;
65
static parea_t clock_parea;
Line 149... Line 146...
149
 
146
 
150
    /*
147
    /*
151
     * To avoid lock ordering problems,
148
     * To avoid lock ordering problems,
152
     * run all expired timeouts as you visit them.
149
     * run all expired timeouts as you visit them.
153
     */
150
     */
154
 
-
 
155
   
151
   
156
    for (; i <= last_clock_tick; i++) {
152
    for (; i <= last_clock_tick; i++) {
157
        clock_update_counters();
153
        clock_update_counters();
158
        spinlock_lock(&CPU->timeoutlock);
154
        spinlock_lock(&CPU->timeoutlock);
159
   
155
   
Line 181... Line 177...
181
 
177
 
182
            f = h->handler;
178
            f = h->handler;
183
            arg = h->arg;
179
            arg = h->arg;
184
            timeout_reinitialize(h);
180
            timeout_reinitialize(h);
185
            spinlock_unlock(&h->lock); 
181
            spinlock_unlock(&h->lock); 
-
 
182
            spinlock_unlock(&CPU->timeoutlock);
-
 
183
 
-
 
184
            f(arg);
-
 
185
 
-
 
186
            spinlock_lock(&CPU->timeoutlock);
-
 
187
        }
-
 
188
        spinlock_unlock(&CPU->timeoutlock);
-
 
189
    }
-
 
190
 
-
 
191
    CPU->missed_clock_ticks = 0;
-
 
192
 
-
 
193
    /*
-
 
194
     * Do CPU usage accounting and find out whether to preempt THREAD.
-
 
195
     */
-
 
196
    if (THREAD) {
-
 
197
        uint64_t ticks;
-
 
198
       
-
 
199
        spinlock_lock(&CPU->lock);
-
 
200
        CPU->needs_relink += 1 + missed_clock_ticks;
-
 
201
        spinlock_unlock(&CPU->lock);   
-
 
202
   
-
 
203
        spinlock_lock(&THREAD->lock);
-
 
204
        if ((ticks = THREAD->ticks)) {
-
 
205
            if (ticks >= 1 + missed_clock_ticks)
-
 
206
                THREAD->ticks -= 1 + missed_clock_ticks;
-
 
207
            else
-
 
208
                THREAD->ticks = 0;
-
 
209
        }
-
 
210
        spinlock_unlock(&THREAD->lock);
-
 
211
       
-
 
212
        if (!ticks && !PREEMPTION_DISABLED) {
-
 
213
            scheduler();
-
 
214
        }
-
 
215
    }
-
 
216
}
-
 
217
 
-
 
218
#elif defined CONFIG_TIMEOUT_FAVL_TREE
-
 
219
 
-
 
220
/** Clock routine
-
 
221
 *
-
 
222
 * Clock routine executed from clock interrupt handler
-
 
223
 * (assuming interrupts_disable()'d). Runs expired timeouts
-
 
224
 * and preemptive scheduling.
-
 
225
 *
-
 
226
 */
-
 
227
void clock(void)
-
 
228
{
-
 
229
    timeout_t *h;
-
 
230
    timeout_handler_t f;
-
 
231
    void *arg;
-
 
232
    count_t missed_clock_ticks = CPU->missed_clock_ticks;
-
 
233
    uint64_t i = CPU->timeout_active_tree.base;
-
 
234
    uint64_t last_clock_tick = i + missed_clock_ticks;
-
 
235
    favltree_node_t *expnode;
-
 
236
 
-
 
237
    /*
-
 
238
     * To avoid lock ordering problems,
-
 
239
     * run all expired timeouts as you visit them.
-
 
240
     */
-
 
241
   
-
 
242
    for (; i <= last_clock_tick; i++) {
-
 
243
        clock_update_counters();
-
 
244
        spinlock_lock(&CPU->timeoutlock);
-
 
245
   
-
 
246
        /*
-
 
247
         * Check whether first timeout (with the smallest key in the tree) time out. If so perform
-
 
248
         * callback function and try next timeout (more timeouts can have same timeout).
-
 
249
         * Function favltree_find_min works in contant time.
-
 
250
         */
-
 
251
        while ((expnode = favltree_find_min(&CPU->timeout_active_tree)) != NULL) {
-
 
252
            h = favltree_get_instance(expnode,timeout_t,node);
-
 
253
            spinlock_lock(&h->lock);
-
 
254
            if (expnode->key != i) {
-
 
255
                /*
-
 
256
                 * Base is increased every for cycle.
-
 
257
                 */
-
 
258
                (CPU->timeout_active_tree.base)++;
-
 
259
                spinlock_unlock(&h->lock);
-
 
260
                break;
-
 
261
            }
-
 
262
           
-
 
263
            /*
-
 
264
             * Delete minimal key from the tree and repair tree structure in
-
 
265
             * logarithmic time.
-
 
266
             */
-
 
267
            favltree_delete_min(&CPU->timeout_active_tree);
-
 
268
 
-
 
269
            f = h->handler;
-
 
270
            arg = h->arg;
-
 
271
            timeout_reinitialize(h);
-
 
272
            spinlock_unlock(&h->lock); 
186
            spinlock_unlock(&CPU->timeoutlock);
273
            spinlock_unlock(&CPU->timeoutlock);
187
 
274
 
188
            f(arg);
275
            f(arg);
189
 
276
 
190
            spinlock_lock(&CPU->timeoutlock);
277
            spinlock_lock(&CPU->timeoutlock);