Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

/projects/cubeos/src_current/kernel/sleep.c

Go to the documentation of this file.
00001 /*  src_experimental/kernel/sleep.c
00002    CubeOS Version 0.4.90 experimental
00003    Copyright (C) 1999,2000 Holger Kenn
00004 
00005    CubeOS is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or any later version.
00009 
00010    CubeOS is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015  */
00020 #include <cubeos.h>
00021 #include <sys_var.h>
00022 #include <ptimer.h>
00023 #include <schedule.h>
00024 #include <list.h>
00025 
00026 /* 
00027 \brief suspends the current thread for a while in the scheduler
00028 \param howlong specifies the number of timer ticks the thread should not run
00029 \ingroup KERN
00030 */
00031 int KERN_psleep (unsigned int howlong)
00032 {
00033         int deltatrack = 0;
00034         int savetime;
00035         struct process *currentprocess;
00036         struct process *thisprocess;
00037         entry *listentry;
00038         int quit = 0;
00039 
00040         disable ();
00041 
00042 
00043         if (LIST_entries (&_KERN_delta) == 0) {
00044                 /* this is the easy case */
00045                 _KERN_ptable[getpid ()].time_delta = howlong;
00046                 LIST_insert_head (&_KERN_delta, &(_KERN_ptable[getpid ()].me));
00047                 enable ();
00048                 return (KERN_suspend (-1));
00049         }
00050         listentry = LIST_head (&_KERN_delta);
00051         thisprocess = &(_KERN_ptable[getpid ()]);
00052         while (!quit) {
00053                 currentprocess = (struct process *) (listentry->data);
00054                 deltatrack += currentprocess->time_delta;
00055                 if (howlong <= deltatrack) {
00056                         /* if we have an earlier deadline than the process in the delta queue */
00057                         /* we have to put ourselves in front and decrement the current processes time_delta by howlong */
00058 
00059                         /* move the running process in front of the current process */
00060                         LIST_insert_before (&(thisprocess->me), listentry);
00061 
00062                         /* adjust the times. First: substract howlong from the current process time */
00063                         currentprocess->time_delta = -howlong;
00064 
00065                         /* then: set our own delta time */
00066                         thisprocess->time_delta = howlong - deltatrack;
00067                         quit = 1;
00068                 } else {
00069                         if (listentry->next) {
00070                                 listentry = listentry->next;    /* if there is another entry, go and check it */
00071                         } else {
00072                                 /* we're at the end of the queue, so we append here */
00073                                 LIST_insert_after (&(thisprocess->me), listentry);
00074                                 thisprocess->time_delta = howlong - deltatrack;
00075                                 quit = 1;
00076                         }
00077                 }
00078         }
00079 
00080         enable ();
00081         return (-1);
00082 }
00083 
00084 /* 
00085 \brief suspends the current thread for a while
00086 \param howlong is the number of seconds the thread is blocking
00087 \ingroup KERN
00088 \todo this is currently implemented by actively watching clockticks and is a waste of cycles.
00089 This has to be changed to use KERN_psleep instead
00090 */
00091 int KERN_ssleep (unsigned int howlong)
00092 {
00093         unsigned int seconds;
00094         unsigned int ticks;
00095 
00096         disable ();
00097         seconds = _time_seconds;
00098         ticks = _time_ticks;
00099         enable ();
00100 
00101         seconds += howlong;
00102 
00103         while (seconds > _time_seconds);
00104         while ((seconds == _time_seconds) && (ticks > _time_ticks));
00105         return (0);
00106 }
00107 
00108 /* 
00109 \brief suspends the current thread for a while
00110 \param howlong is the number of microseconds the thread is blocking
00111 \ingroup KERN
00112 \todo this is currently implemented by actively watching clockticks and a is waste of cycles.
00113 This has to be changed to use KERN_psleep instead. For shorter times, a timed loop
00114 like in BOGOMIPS of Linux should be used instead.
00115 */
00116 int KERN_usleep (unsigned int howlong)
00117 {
00118         unsigned int seconds;
00119         unsigned int ticks;
00120 
00121 
00122         disable ();
00123         seconds = _time_seconds;
00124         ticks = _time_ticks;
00125         enable ();
00126         ticks += howlong * TICKS_PER_SECOND / 1000000;
00127         seconds += ticks / TICKS_PER_SECOND;
00128         ticks = ticks % TICKS_PER_SECOND;
00129         while (seconds > _time_seconds);
00130         while ((seconds == _time_seconds) && (ticks > _time_ticks));
00131         return (0);
00132 
00133 }

Generated on Thu Feb 20 15:38:45 2003 for cubeOS by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002