Subversion Repositories freemyipod

Rev

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

Rev 15 Rev 34
Line 29... Line 29...
29
 
29
 
30
 
30
 
31
struct scheduler_thread scheduler_threads[MAX_THREADS] IBSS_ATTR;
31
struct scheduler_thread scheduler_threads[MAX_THREADS] IBSS_ATTR;
32
struct scheduler_thread* current_thread IBSS_ATTR;
32
struct scheduler_thread* current_thread IBSS_ATTR;
33
uint32_t last_tick IBSS_ATTR;
33
uint32_t last_tick IBSS_ATTR;
-
 
34
bool scheduler_frozen IBSS_ATTR;
34
extern struct wakeup dbgwakeup;
35
extern struct wakeup dbgwakeup;
35
 
36
 
36
 
37
 
37
void mutex_init(struct mutex* obj)
38
void mutex_init(struct mutex* obj)
38
{
39
{
Line 215... Line 216...
215
}
216
}
216
 
217
 
217
void scheduler_init(void)
218
void scheduler_init(void)
218
{
219
{
219
    memset(scheduler_threads, 0, sizeof(scheduler_threads));
220
    memset(scheduler_threads, 0, sizeof(scheduler_threads));
-
 
221
    scheduler_frozen = false;
220
    last_tick = USEC_TIMER;
222
    last_tick = USEC_TIMER;
221
    current_thread = scheduler_threads;
223
    current_thread = scheduler_threads;
222
    current_thread->state = THREAD_RUNNING;
224
    current_thread->state = THREAD_RUNNING;
223
    current_thread->startusec = last_tick;
225
    current_thread->startusec = last_tick;
224
    current_thread->name = "idle thread";
226
    current_thread->name = "idle thread";
225
    current_thread->stack = (uint32_t*)-1;
227
    current_thread->stack = (uint32_t*)-1;
226
    setup_tick();
228
    setup_tick();
227
}
229
}
228
 
230
 
-
 
231
void scheduler_freeze(bool value)
-
 
232
{
-
 
233
    scheduler_frozen = value;
-
 
234
}
-
 
235
 
229
void scheduler_switch(int thread)
236
void scheduler_switch(int thread)
230
{
237
{
231
    int i;
238
    int i;
232
    uint32_t score, best;
239
    uint32_t score, best;
233
    uint32_t usec = USEC_TIMER;
240
    uint32_t usec = USEC_TIMER;
Line 252... Line 259...
252
            scheduler_threads[i].cpuload = scheduler_threads[i].cputime_current / SCHEDULER_TICK;
259
            scheduler_threads[i].cpuload = scheduler_threads[i].cputime_current / SCHEDULER_TICK;
253
            scheduler_threads[i].cputime_current = 0;
260
            scheduler_threads[i].cputime_current = 0;
254
        }
261
        }
255
    }
262
    }
256
 
263
 
257
    for (i = 0; i < MAX_THREADS; i++)
-
 
258
        if (scheduler_threads[i].state == THREAD_BLOCKED
-
 
259
         && scheduler_threads[i].timeout != -1
-
 
260
         && TIME_AFTER(usec, scheduler_threads[i].blocked_since
-
 
261
                           + scheduler_threads[i].timeout))
-
 
262
        {
-
 
263
            if (scheduler_threads[i].block_type == THREAD_BLOCK_MUTEX)
-
 
264
                mutex_remove_from_queue((struct mutex*)scheduler_threads[i].blocked_by,
-
 
265
                                        &scheduler_threads[i]);
-
 
266
            scheduler_threads[i].state = THREAD_READY;
-
 
267
            scheduler_threads[i].block_type = THREAD_NOT_BLOCKED;
-
 
268
            scheduler_threads[i].blocked_by = NULL;
-
 
269
            scheduler_threads[i].timeout = 0;
264
    if (scheduler_frozen) thread = 0;
270
        }
-
 
271
 
-
 
272
    if (thread >= 0 && thread < MAX_THREADS && scheduler_threads[thread].state == THREAD_READY)
-
 
273
        current_thread = &scheduler_threads[thread];
-
 
274
    else
265
    else
275
    {
266
    {
276
        thread = 0;
-
 
277
        best = 0xffffffff;
-
 
278
        for (i = 0; i < MAX_THREADS; i++)
267
        for (i = 0; i < MAX_THREADS; i++)
279
            if (scheduler_threads[i].state == THREAD_READY && scheduler_threads[i].priority)
268
            if (scheduler_threads[i].state == THREAD_BLOCKED
-
 
269
             && scheduler_threads[i].timeout != -1
-
 
270
             && TIME_AFTER(usec, scheduler_threads[i].blocked_since
-
 
271
                               + scheduler_threads[i].timeout))
280
            {
272
            {
-
 
273
                if (scheduler_threads[i].block_type == THREAD_BLOCK_MUTEX)
281
                score = scheduler_threads[i].cputime_current / scheduler_threads[i].priority;
274
                    mutex_remove_from_queue((struct mutex*)scheduler_threads[i].blocked_by,
-
 
275
                                            &scheduler_threads[i]);
-
 
276
                scheduler_threads[i].state = THREAD_READY;
-
 
277
                scheduler_threads[i].block_type = THREAD_NOT_BLOCKED;
-
 
278
                scheduler_threads[i].blocked_by = NULL;
-
 
279
                scheduler_threads[i].timeout = 0;
-
 
280
            }
-
 
281
 
-
 
282
        if (thread >= 0 && thread < MAX_THREADS && scheduler_threads[thread].state == THREAD_READY)
-
 
283
            current_thread = &scheduler_threads[thread];
-
 
284
        else
-
 
285
        {
-
 
286
            thread = 0;
282
                if (score < best)
287
            best = 0xffffffff;
-
 
288
            for (i = 0; i < MAX_THREADS; i++)
-
 
289
                if (scheduler_threads[i].state == THREAD_READY && scheduler_threads[i].priority)
283
                {
290
                {
-
 
291
                    score = scheduler_threads[i].cputime_current / scheduler_threads[i].priority;
-
 
292
                    if (score < best)
-
 
293
                    {
284
                    best = score;
294
                        best = score;
285
                    thread = i;
295
                        thread = i;
-
 
296
                    }
286
                }
297
                }
287
            }
298
        }
288
    }
299
    }
289
 
300
 
290
    current_thread = &scheduler_threads[thread];
301
    current_thread = &scheduler_threads[thread];
291
    current_thread->state = THREAD_RUNNING;
302
    current_thread->state = THREAD_RUNNING;
292
    current_thread->startusec = USEC_TIMER;
303
    current_thread->startusec = USEC_TIMER;