00001
00002
00011
00012
00013
00014
00015
00016
00017 #include <l4/sys/syscalls.h>
00018 #include <l4/thread/thread.h>
00019 #include <l4/semaphore/semaphore.h>
00020
00021 #include <l4/dde_linux/dde.h>
00022
00023
00024 #include <linux/sched.h>
00025
00026
00027 #include "internal.h"
00028 #include "__config.h"
00029 #include "fastcall.h"
00030
00044 static inline int try_to_wake_up(struct task_struct *p, int synchronous)
00045 {
00046 p->state = TASK_RUNNING;
00047
00048
00049 l4semaphore_up(&p->dde_sem);
00050
00051 return 1;
00052 }
00053
00056 inline int FASTCALL(wake_up_process(struct task_struct *p))
00057 {
00058 return try_to_wake_up(p, 0);
00059 }
00060
00062 static void process_timeout(unsigned long __data)
00063 {
00064 struct task_struct *p = (struct task_struct *) __data;
00065
00066 wake_up_process(p);
00067 }
00068
00071 signed long FASTCALL(schedule_timeout(signed long timeout))
00072 {
00073 struct timer_list timer;
00074 unsigned long expire;
00075
00076 switch (timeout)
00077 {
00078 case MAX_SCHEDULE_TIMEOUT:
00079
00080
00081
00082
00083
00084
00085
00086 schedule();
00087 goto out;
00088 default:
00089
00090
00091
00092
00093
00094
00095
00096 if (timeout < 0)
00097 {
00098 LOG_Error("schedule_timeout: wrong timeout "
00099 "value %lx", timeout);
00100 current->state = TASK_RUNNING;
00101 goto out;
00102 }
00103 }
00104
00105 expire = timeout + jiffies;
00106
00107 init_timer(&timer);
00108 timer.expires = expire;
00109 timer.data = (unsigned long) current;
00110 timer.function = process_timeout;
00111
00112 add_timer(&timer);
00113 schedule();
00114 del_timer_sync(&timer);
00115
00116 timeout = expire - jiffies;
00117
00118 out:
00119 return timeout < 0 ? 0 : timeout;
00120 }
00121
00124 void schedule(void)
00125 {
00126
00127 switch (current->state)
00128 {
00129 case TASK_RUNNING:
00130
00131 #if SCHED_YIELD_OPT
00132 l4thread_usleep(SCHED_YIELD_TO);
00133 #else
00134 l4_yield();
00135 #endif
00136 break;
00137
00138 case TASK_UNINTERRUPTIBLE:
00139 case TASK_INTERRUPTIBLE:
00140
00141 l4semaphore_down(¤t->dde_sem);
00142 break;
00143
00144 default:
00145 Panic("current->state unknown (%ld)\n", current->state);
00146 }
00147 }
00148
00150 static inline void __wake_up_common(wait_queue_head_t * q, unsigned int mode,
00151 int nr_exclusive, const int sync)
00152 {
00153 struct list_head *tmp, *head;
00154 struct task_struct *p;
00155
00156 CHECK_MAGIC_WQHEAD(q);
00157 head = &q->task_list;
00158 WQ_CHECK_LIST_HEAD(head);
00159 tmp = head->next;
00160 while (tmp != head)
00161 {
00162 unsigned int state;
00163 wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
00164
00165 tmp = tmp->next;
00166 CHECK_MAGIC(curr->__magic);
00167 p = curr->task;
00168 state = p->state;
00169 if (state & mode)
00170 {
00171 WQ_NOTE_WAKER(curr);
00172 if (try_to_wake_up(p, sync) && curr->flags && !--nr_exclusive)
00173 break;
00174 }
00175 }
00176 }
00177
00180 void FASTCALL(__wake_up(wait_queue_head_t * q, unsigned int mode, int nr))
00181 {
00182 if (q)
00183 {
00184 unsigned long flags;
00185 wq_read_lock_irqsave(&q->lock, flags);
00186 __wake_up_common(q, mode, nr, 0);
00187 wq_read_unlock_irqrestore(&q->lock, flags);
00188 }
00189 }
00190
00193 void FASTCALL(__wake_up_sync(wait_queue_head_t * q, unsigned int mode, int nr))
00194 {
00195 if (q)
00196 {
00197 unsigned long flags;
00198 wq_read_lock_irqsave(&q->lock, flags);
00199 __wake_up_common(q, mode, nr, 1);
00200 wq_read_unlock_irqrestore(&q->lock, flags);
00201 }
00202 }
00203
00204 #define SLEEP_ON_VAR \
00205 unsigned long flags; \
00206 wait_queue_t wait; \
00207 init_waitqueue_entry(&wait, current);
00208
00209 #define SLEEP_ON_HEAD \
00210 wq_write_lock_irqsave(&q->lock,flags); \
00211 __add_wait_queue(q, &wait); \
00212 wq_write_unlock(&q->lock);
00213
00214 #define SLEEP_ON_TAIL \
00215 wq_write_lock_irq(&q->lock); \
00216 __remove_wait_queue(q, &wait); \
00217 wq_write_unlock_irqrestore(&q->lock,flags);
00218
00221 void FASTCALL(interruptible_sleep_on(wait_queue_head_t * q))
00222 {
00223 SLEEP_ON_VAR current->state = TASK_INTERRUPTIBLE;
00224
00225 SLEEP_ON_HEAD schedule();
00226 SLEEP_ON_TAIL
00227 }
00228
00231 long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t * q, long timeout))
00232 {
00233 SLEEP_ON_VAR current->state = TASK_INTERRUPTIBLE;
00234
00235 SLEEP_ON_HEAD timeout = schedule_timeout(timeout);
00236 SLEEP_ON_TAIL return timeout;
00237 }
00238
00241 void FASTCALL(sleep_on(wait_queue_head_t * q))
00242 {
00243 SLEEP_ON_VAR current->state = TASK_UNINTERRUPTIBLE;
00244
00245 SLEEP_ON_HEAD schedule();
00246 SLEEP_ON_TAIL
00247 }
00248
00251 long FASTCALL(sleep_on_timeout(wait_queue_head_t * q, long timeout))
00252 {
00253 SLEEP_ON_VAR current->state = TASK_UNINTERRUPTIBLE;
00254
00255 SLEEP_ON_HEAD timeout = schedule_timeout(timeout);
00256 SLEEP_ON_TAIL return timeout;
00257 }
00258
00262 void daemonize(void) {
00263 LOGd(DEBUG_MSG, "dde: dummy daemonize() call");
00264 }