watch.c

Go to the documentation of this file.
00001 /*!
00002  * \file   cpu_reserve/server/src/watch.c
00003  * \brief  Preemption watcher
00004  *
00005  * \date   09/18/2004
00006  * \author Jork Loeser <jork.loeser@inf.tu-dresden.de>
00007  *
00008  */
00009 /* (c) 2004 Technische Universitaet Dresden
00010  * This file is part of DROPS, which is distributed under the terms of the
00011  * GNU General Public License 2. Please see the COPYING file for details.
00012  */
00013 
00014 #include <l4/sys/rt_sched.h>
00015 #include <l4/log/l4log.h>
00016 #include <l4/util/macros.h>
00017 #include <l4/rt_mon/histogram.h>
00018 #include <l4/env/errno.h>
00019 #include "cpu_reserve-client.h"
00020 #include "sched.h"
00021 #include "watch.h"
00022 #include "monitor.h"
00023 
00024 extern int watch_verbose;
00025 
00026 /*!\brief Compare threads, ignoring chief, nest and site
00027  */
00028 static inline int thread_equal(l4_threadid_t a, l4_threadid_t b){
00029     return a.id.lthread == b.id.lthread &&
00030         a.id.task == b.id.task;
00031 }
00032 
00033 /*!\brief Will be called by our own watcher thread on timeslice overrrun
00034  */
00035 static int watch_hit_ts(const l4_threadid_t *thread, int id){
00036     int i;
00037 
00038     lock_scheds();
00039     /* find the thread-id. */
00040     for(i=0;i<sched_cur_threads;i++){
00041         if(thread_equal(scheds[i]->thread, *thread) &&
00042            scheds[i]->id == 1 &&
00043            !is_dp(scheds[i])){
00044             if(scheds[i]->watch) scheds[i]->watch[id]++;
00045             unlock_scheds();
00046             return 0;
00047         }
00048     }
00049     unlock_scheds();
00050     return -L4_ENOTFOUND;
00051 }
00052 
00053 void watcher_fn(void*arg){
00054     l4_rt_preemption_t dw;
00055     l4_msgdope_t result;
00056     l4_threadid_t thread;
00057     l4semaphore_t *end_sem = (l4semaphore_t*)arg;
00058 
00059     LOGdL(watch_verbose, "Waiting for Preemption-IPCs");
00060 
00061     while (1) {
00062         // wait for preemption IPC
00063         if (l4_ipc_wait(&thread,
00064                         L4_IPC_SHORT_MSG, (l4_umword_t*)&dw.lh.low, (l4_umword_t*)&dw.lh.high,
00065                         L4_IPC_NEVER, &result) == 0){
00066 
00067             if(l4_thread_equal(thread, main_id)){
00068                 /* we should stop */
00069                 l4semaphore_up(end_sem);
00070                 l4_sleep_forever();
00071             }
00072             switch(dw.p.type){
00073             case L4_RT_PREEMPT_TIMESLICE:
00074                 LOGd(watch_verbose, "TS "l4util_idfmt"/%d",
00075                      l4util_idstr(thread), dw.p.id);
00076                 watch_hit_ts(&thread, dw.p.id);
00077                 break;
00078             case L4_RT_PREEMPT_DEADLINE: {
00079                 LOGd(watch_verbose, "DL "l4util_idfmt, l4util_idstr(thread));
00080                 if(monitor_enable){
00081                     int err;
00082                     l4_threadid_t next;
00083                     l4_cpu_time_t time;
00084                     l4_umword_t prio;
00085 
00086                     if((err = fiasco_get_cputime(thread, &next,
00087                                                  &time, &prio))!=0){
00088                         LOG_Error("fiasco_get_cputime()");
00089                         break;
00090                     }
00091 
00092                     monitor_thread_dl(&thread, time);
00093                 }
00094                 break;
00095             }
00096             }
00097         } else
00098             LOG("Preempt-receive returned %lx", L4_IPC_ERROR(result));
00099     }
00100 }

CPU reservation server Reference Manual, written by Jork Loeser  © 2004