source: mainline/generic/src/time/timeout.c@ 953b0f33

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 953b0f33 was cf26ba9, checked in by Jakub Jermar <jakub@…>, 20 years ago

Improve Doxygen-comments.

  • Property mode set to 100644
File size: 4.9 KB
RevLine 
[f761f1eb]1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[cf26ba9]29/**
30 * @file timeout.c
31 * @brief Timeout management functions.
32 */
33
[f761f1eb]34#include <time/timeout.h>
35#include <typedefs.h>
36#include <arch/types.h>
37#include <config.h>
[02a99d2]38#include <panic.h>
[f761f1eb]39#include <synch/spinlock.h>
40#include <func.h>
41#include <cpu.h>
42#include <arch/asm.h>
43#include <arch.h>
44
[70527f1]45
46/** Initialize timeouts
47 *
48 * Initialize kernel timeouts.
49 *
50 */
[f761f1eb]51void timeout_init(void)
52{
[2d93f1f9]53 spinlock_initialize(&CPU->timeoutlock, "timeout_lock");
[43114c5]54 list_initialize(&CPU->timeout_active_head);
[f761f1eb]55}
56
57
[ba1b2194]58/** Reinitialize timeout
[70527f1]59 *
[ba1b2194]60 * Initialize all members except the lock.
[70527f1]61 *
[ba1b2194]62 * @param t Timeout to be initialized.
[70527f1]63 *
64 */
[f761f1eb]65void timeout_reinitialize(timeout_t *t)
66{
67 t->cpu = NULL;
68 t->ticks = 0;
69 t->handler = NULL;
70 t->arg = NULL;
71 link_initialize(&t->link);
72}
73
[70527f1]74
[ba1b2194]75/** Initialize timeout
[70527f1]76 *
[ba1b2194]77 * Initialize all members including the lock.
[70527f1]78 *
[ba1b2194]79 * @param t Timeout to be initialized.
[70527f1]80 *
81 */
[f761f1eb]82void timeout_initialize(timeout_t *t)
83{
[2d93f1f9]84 spinlock_initialize(&t->lock, "timeout_t_lock");
[f761f1eb]85 timeout_reinitialize(t);
86}
87
[70527f1]88
[ba1b2194]89/** Register timeout
[70527f1]90 *
[ba1b2194]91 * Insert timeout handler f (with argument arg)
92 * to timeout list and make it execute in
[70527f1]93 * time microseconds (or slightly more).
94 *
[ba1b2194]95 * @param t Timeout structure.
[a783ca4]96 * @param time Number of usec in the future to execute
[70527f1]97 * the handler.
98 * @param f Timeout handler function.
99 * @param arg Timeout handler argument.
100 *
[f761f1eb]101 */
[ba1b2194]102void timeout_register(timeout_t *t, __u64 time, timeout_handler_t f, void *arg)
[f761f1eb]103{
[2cf5634]104 timeout_t *hlp = NULL;
[f761f1eb]105 link_t *l, *m;
[22f7769]106 ipl_t ipl;
[f761f1eb]107 __u64 sum;
108
[22f7769]109 ipl = interrupts_disable();
[43114c5]110 spinlock_lock(&CPU->timeoutlock);
[f761f1eb]111 spinlock_lock(&t->lock);
[76cec1e]112
[f761f1eb]113 if (t->cpu)
[747a2476]114 panic("t->cpu != 0");
[f761f1eb]115
[43114c5]116 t->cpu = CPU;
[f761f1eb]117 t->ticks = us2ticks(time);
118
119 t->handler = f;
120 t->arg = arg;
[76cec1e]121
[f761f1eb]122 /*
123 * Insert t into the active timeouts list according to t->ticks.
124 */
125 sum = 0;
[43114c5]126 l = CPU->timeout_active_head.next;
127 while (l != &CPU->timeout_active_head) {
[f761f1eb]128 hlp = list_get_instance(l, timeout_t, link);
129 spinlock_lock(&hlp->lock);
130 if (t->ticks < sum + hlp->ticks) {
131 spinlock_unlock(&hlp->lock);
132 break;
133 }
134 sum += hlp->ticks;
135 spinlock_unlock(&hlp->lock);
136 l = l->next;
137 }
[5a2e9bbb]138
[f761f1eb]139 m = l->prev;
140 list_prepend(&t->link, m); /* avoid using l->prev */
141
142 /*
143 * Adjust t->ticks according to ticks accumulated in h's predecessors.
144 */
145 t->ticks -= sum;
146
147 /*
148 * Decrease ticks of t's immediate succesor by t->ticks.
149 */
[43114c5]150 if (l != &CPU->timeout_active_head) {
[f761f1eb]151 spinlock_lock(&hlp->lock);
152 hlp->ticks -= t->ticks;
153 spinlock_unlock(&hlp->lock);
154 }
155
156 spinlock_unlock(&t->lock);
[43114c5]157 spinlock_unlock(&CPU->timeoutlock);
[22f7769]158 interrupts_restore(ipl);
[f761f1eb]159}
160
[70527f1]161
[ba1b2194]162/** Unregister timeout
[70527f1]163 *
164 * Remove timeout from timeout list.
165 *
166 * @param t Timeout to unregister.
167 *
[ba1b2194]168 * @return true on success, false on failure.
[70527f1]169 */
[ba1b2194]170bool timeout_unregister(timeout_t *t)
[f761f1eb]171{
172 timeout_t *hlp;
173 link_t *l;
[22f7769]174 ipl_t ipl;
[f761f1eb]175
176grab_locks:
[22f7769]177 ipl = interrupts_disable();
[f761f1eb]178 spinlock_lock(&t->lock);
179 if (!t->cpu) {
180 spinlock_unlock(&t->lock);
[22f7769]181 interrupts_restore(ipl);
[ba1b2194]182 return false;
[f761f1eb]183 }
184 if (!spinlock_trylock(&t->cpu->timeoutlock)) {
185 spinlock_unlock(&t->lock);
[22f7769]186 interrupts_restore(ipl);
[f761f1eb]187 goto grab_locks;
188 }
189
190 /*
191 * Now we know for sure that t hasn't been activated yet
192 * and is lurking in t->cpu->timeout_active_head queue.
193 */
194
195 l = t->link.next;
196 if (l != &t->cpu->timeout_active_head) {
197 hlp = list_get_instance(l, timeout_t, link);
198 spinlock_lock(&hlp->lock);
199 hlp->ticks += t->ticks;
200 spinlock_unlock(&hlp->lock);
201 }
202
203 list_remove(&t->link);
204 spinlock_unlock(&t->cpu->timeoutlock);
205
206 timeout_reinitialize(t);
207 spinlock_unlock(&t->lock);
208
[22f7769]209 interrupts_restore(ipl);
[ba1b2194]210 return true;
[f761f1eb]211}
Note: See TracBrowser for help on using the repository browser.