Subversion Repositories HelenOS

Rev

Rev 2336 | Rev 2421 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2336 Rev 2416
Line 121... Line 121...
121
        } else
121
        } else
122
            uptime->useconds += 1000000 / HZ;
122
            uptime->useconds += 1000000 / HZ;
123
    }
123
    }
124
}
124
}
125
 
125
 
-
 
126
#if defined CONFIG_TIMEOUT_AVL_TREE || \
126
#ifdef CONFIG_TIMEOUT_EXTAVL_TREE
127
    defined CONFIG_TIMEOUT_EXTAVL_TREE
127
 
128
 
128
/** Clock routine
129
/** Clock routine
129
 *
130
 *
130
 * Clock routine executed from clock interrupt handler
131
 * Clock routine executed from clock interrupt handler
131
 * (assuming interrupts_disable()'d). Runs expired timeouts
132
 * (assuming interrupts_disable()'d). Runs expired timeouts
Line 136... Line 137...
136
{
137
{
137
    timeout_t *h;
138
    timeout_t *h;
138
    timeout_handler_t f;
139
    timeout_handler_t f;
139
    void *arg;
140
    void *arg;
140
    count_t missed_clock_ticks = CPU->missed_clock_ticks;
141
    count_t missed_clock_ticks = CPU->missed_clock_ticks;
141
    uint64_t *i = &(CPU->timeout_active_tree.basetime);
142
    uint64_t *i = &(CPU->timeout_active_tree.base);
142
    uint64_t absolute_clock_ticks = *i +
143
    uint64_t absolute_clock_ticks = *i + missed_clock_ticks;
-
 
144
#if defined CONFIG TIMEOUT_AVL_TREE
143
                                    missed_clock_ticks;
145
    avltree_node_t *expnode;
144
    extavltree_node_t *head = &(CPU->timeout_active_tree.head);
146
#elif defined CONFIG_TIMEOUT_EXTAVL_TREE
145
    extavltree_node_t *expnode = head->next;
147
    extavltree_node_t *expnode;
-
 
148
#endif
146
   
149
 
147
    /*
150
    /*
148
     * To avoid lock ordering problems,
151
     * To avoid lock ordering problems,
149
     * run all expired timeouts as you visit them.
152
     * run all expired timeouts as you visit them.
150
     */
153
     */
151
 
154
 
152
    for (; *i <= absolute_clock_ticks; (*i)++) {
155
    for (; *i <= absolute_clock_ticks; (*i)++) {
-
 
156
        /*
-
 
157
         * Basetime is encreased by missed clock ticks + 1 !!
-
 
158
         */
-
 
159
       
153
        clock_update_counters();
160
        clock_update_counters();
154
        spinlock_lock(&CPU->timeoutlock);
161
        spinlock_lock(&CPU->timeoutlock);
155
 
162
       
-
 
163
        /*
-
 
164
         * Check whether first timeout in list time out. If so perform callback function and try
-
 
165
         * next timeout (more timeouts can have same timeout).
-
 
166
         */
156
        while ((expnode = head->next) != head) {
167
        while ((expnode = CPU->timeout_active_tree.head.next) != &(CPU->timeout_active_tree.head)) {
157
            h = extavltree_get_instance(expnode,timeout_t,node);
168
            h = extavltree_get_instance(expnode,timeout_t,node);
158
            spinlock_lock(&h->lock);
169
            spinlock_lock(&h->lock);
159
            if (expnode->key != *i) {
170
            if (expnode->key != *i) {
160
                spinlock_unlock(&h->lock);
171
                spinlock_unlock(&h->lock);
161
                break;
172
                break;
162
            }
173
            }
163
           
174
           
-
 
175
            /*
-
 
176
             * Delete first node in the list and repair tree structure in
-
 
177
             * constant time.
-
 
178
             */
-
 
179
#if defined CONFIG TIMEOUT_AVL_TREE
-
 
180
            avltree_delete_min(&CPU->timeout_active_tree);
-
 
181
#elif defined CONFIG_TIMEOUT_EXTAVL_TREE
164
            extavltree_delete_min(&CPU->timeout_active_tree);
182
            extavltree_delete_min(&CPU->timeout_active_tree);
-
 
183
#endif
165
 
184
 
166
            f = h->handler;
185
            f = h->handler;
167
            arg = h->arg;
186
            arg = h->arg;
168
            timeout_reinitialize(h);
187
            timeout_reinitialize(h);
169
            spinlock_unlock(&h->lock); 
188
            spinlock_unlock(&h->lock); 
Line 201... Line 220...
201
            scheduler();
220
            scheduler();
202
        }
221
        }
203
    }
222
    }
204
}
223
}
205
 
224
 
-
 
225
#elif defined CONFIG_TIMEOUT_EXTAVLREL_TREE
-
 
226
 
-
 
227
/** Clock routine
-
 
228
 *
-
 
229
 * Clock routine executed from clock interrupt handler
-
 
230
 * (assuming interrupts_disable()'d). Runs expired timeouts
-
 
231
 * and preemptive scheduling.
-
 
232
 *
-
 
233
 */
-
 
234
void clock(void)
-
 
235
{
-
 
236
    extavltree_node_t *expnode;
-
 
237
    timeout_t *h;
-
 
238
    timeout_handler_t f;
-
 
239
    void *arg;
-
 
240
    count_t missed_clock_ticks = CPU->missed_clock_ticks;
-
 
241
    int i;
-
 
242
 
-
 
243
    /*
-
 
244
     * To avoid lock ordering problems,
-
 
245
     * run all expired timeouts as you visit them.
-
 
246
     */
-
 
247
    for (i = 0; i <= missed_clock_ticks; i++) {
-
 
248
        clock_update_counters();
-
 
249
        spinlock_lock(&CPU->timeoutlock);
-
 
250
 
-
 
251
        /*
-
 
252
         * Check whether first timeout in list time out. If so perform callback function and try
-
 
253
         * next timeout (more timeouts can have same timeout).
-
 
254
         */
-
 
255
        while ((expnode = CPU->timeout_active_tree.head.next) != &(CPU->timeout_active_tree.head)) {
-
 
256
            h = list_get_instance(l, timeout_t, link);
-
 
257
            spinlock_lock(&h->lock);
-
 
258
            if (expnode->key != 0) {
-
 
259
                expnode->key--;
-
 
260
                spinlock_unlock(&h->lock);
-
 
261
                break;
-
 
262
            }
-
 
263
           
-
 
264
            /*
-
 
265
             * Delete first node in the list and repair tree structure in
-
 
266
             * constant time. Be careful of expnode's key, it must be 0!
-
 
267
             */
-
 
268
            extavltree_delete_min(&CPU->timeout_active_tree);
-
 
269
           
-
 
270
            f = h->handler;
-
 
271
            arg = h->arg;
-
 
272
            timeout_reinitialize(h);
-
 
273
            spinlock_unlock(&h->lock); 
-
 
274
            spinlock_unlock(&CPU->timeoutlock);
-
 
275
 
-
 
276
            f(arg);
-
 
277
 
-
 
278
            spinlock_lock(&CPU->timeoutlock);
-
 
279
        }
-
 
280
        spinlock_unlock(&CPU->timeoutlock);
-
 
281
    }
-
 
282
    CPU->missed_clock_ticks = 0;
-
 
283
 
-
 
284
    /*
-
 
285
     * Do CPU usage accounting and find out whether to preempt THREAD.
-
 
286
     */
-
 
287
 
-
 
288
    if (THREAD) {
-
 
289
        uint64_t ticks;
-
 
290
       
-
 
291
        spinlock_lock(&CPU->lock);
-
 
292
        CPU->needs_relink += 1 + missed_clock_ticks;
-
 
293
        spinlock_unlock(&CPU->lock);   
-
 
294
   
-
 
295
        spinlock_lock(&THREAD->lock);
-
 
296
        if ((ticks = THREAD->ticks)) {
-
 
297
            if (ticks >= 1 + missed_clock_ticks)
-
 
298
                THREAD->ticks -= 1 + missed_clock_ticks;
-
 
299
            else
-
 
300
                THREAD->ticks = 0;
-
 
301
        }
-
 
302
        spinlock_unlock(&THREAD->lock);
-
 
303
       
-
 
304
        if (!ticks && !PREEMPTION_DISABLED) {
-
 
305
            scheduler();
-
 
306
        }
-
 
307
    }
-
 
308
}
-
 
309
 
-
 
310
 
206
 
311
 
207
#else
312
#else
208
 
313
 
209
 
314
 
210
/** Clock routine
315
/** Clock routine
Line 274... Line 379...
274
       
379
       
275
        if (!ticks && !PREEMPTION_DISABLED) {
380
        if (!ticks && !PREEMPTION_DISABLED) {
276
            scheduler();
381
            scheduler();
277
        }
382
        }
278
    }
383
    }
279
 
-
 
280
}
384
}
281
 
385
 
282
#endif
386
#endif
283
/** @}
387
/** @}
284
 */
388
 */