source: mainline/kernel/generic/src/time/clock.c@ 2bc137c2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2bc137c2 was 11675207, checked in by jermar <jermar@…>, 17 years ago

Move everything to kernel/.

  • 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
[1bb2e7a]29/** @addtogroup time
[b45c443]30 * @{
31 */
32
[cf26ba9]33/**
[b45c443]34 * @file
[cf26ba9]35 * @brief High-level clock interrupt handler.
36 *
37 * This file contains the clock() function which is the source
38 * of preemption. It is also responsible for executing expired
39 * timeouts.
40 */
41
[f761f1eb]42#include <time/clock.h>
43#include <time/timeout.h>
44#include <arch/types.h>
45#include <config.h>
46#include <synch/spinlock.h>
47#include <synch/waitq.h>
48#include <func.h>
49#include <proc/scheduler.h>
50#include <cpu.h>
51#include <arch.h>
[5c9a08b]52#include <adt/list.h>
[23684b7]53#include <atomic.h>
[1084a784]54#include <proc/thread.h>
[d6e5cbc]55#include <sysinfo/sysinfo.h>
56#include <arch/barrier.h>
57
58/* Pointers to public variables with time */
59struct ptime {
[7f1c620]60 unative_t seconds1;
61 unative_t useconds;
62 unative_t seconds2;
[d6e5cbc]63};
64struct ptime *public_time;
65/* Variable holding fragment of second, so that we would update
66 * seconds correctly
67 */
[7f1c620]68static unative_t secfrag = 0;
[d6e5cbc]69
70/** Initialize realtime clock counter
71 *
72 * The applications (and sometimes kernel) need to access accurate
73 * information about realtime data. We allocate 1 page with these
74 * data and update it periodically.
75 *
76 *
77 */
78void clock_counter_init(void)
79{
80 void *faddr;
81
[2e9eae2]82 faddr = frame_alloc(0, FRAME_ATOMIC);
[d6e5cbc]83 if (!faddr)
84 panic("Cannot allocate page for clock");
85
86 public_time = (struct ptime *)PA2KA(faddr);
87
88 /* TODO: We would need some arch dependent settings here */
[fd8302d]89 public_time->seconds1 = 0;
90 public_time->seconds2 = 0;
[d6e5cbc]91 public_time->useconds = 0;
92
[7f1c620]93 sysinfo_set_item_val("clock.faddr", NULL, (unative_t)faddr);
[d6e5cbc]94}
95
96
97/** Update public counters
98 *
99 * Update it only on first processor
100 * TODO: Do we really need so many write barriers?
101 */
102static void clock_update_counters(void)
103{
104 if (CPU->id == 0) {
105 secfrag += 1000000/HZ;
106 if (secfrag >= 1000000) {
[fd8302d]107 secfrag -= 1000000;
108 public_time->seconds1++;
[d6e5cbc]109 write_barrier();
[fd8302d]110 public_time->useconds = secfrag;
111 write_barrier();
112 public_time->seconds2 = public_time->seconds1;
[d6e5cbc]113 } else
114 public_time->useconds += 1000000/HZ;
115 }
116}
[f761f1eb]117
[70527f1]118/** Clock routine
119 *
120 * Clock routine executed from clock interrupt handler
[22f7769]121 * (assuming interrupts_disable()'d). Runs expired timeouts
[70527f1]122 * and preemptive scheduling.
123 *
[f761f1eb]124 */
125void clock(void)
126{
127 link_t *l;
128 timeout_t *h;
[ba1b2194]129 timeout_handler_t f;
[f761f1eb]130 void *arg;
[8cf8ee6]131 count_t missed_clock_ticks = CPU->missed_clock_ticks;
[c93e805]132 int i;
[f761f1eb]133
134 /*
135 * To avoid lock ordering problems,
136 * run all expired timeouts as you visit them.
137 */
[8cf8ee6]138 for (i = 0; i <= missed_clock_ticks; i++) {
[d6e5cbc]139 clock_update_counters();
[c93e805]140 spinlock_lock(&CPU->timeoutlock);
141 while ((l = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
142 h = list_get_instance(l, timeout_t, link);
143 spinlock_lock(&h->lock);
144 if (h->ticks-- != 0) {
145 spinlock_unlock(&h->lock);
146 break;
147 }
148 list_remove(l);
149 f = h->handler;
150 arg = h->arg;
151 timeout_reinitialize(h);
152 spinlock_unlock(&h->lock);
153 spinlock_unlock(&CPU->timeoutlock);
[f761f1eb]154
[c93e805]155 f(arg);
[f761f1eb]156
[c93e805]157 spinlock_lock(&CPU->timeoutlock);
158 }
159 spinlock_unlock(&CPU->timeoutlock);
[f761f1eb]160 }
[c93e805]161 CPU->missed_clock_ticks = 0;
[f761f1eb]162
163 /*
[43114c5]164 * Do CPU usage accounting and find out whether to preempt THREAD.
[f761f1eb]165 */
166
[43114c5]167 if (THREAD) {
[7f1c620]168 uint64_t ticks;
[dbe9ff0]169
[43114c5]170 spinlock_lock(&CPU->lock);
[8cf8ee6]171 CPU->needs_relink += 1 + missed_clock_ticks;
[43114c5]172 spinlock_unlock(&CPU->lock);
[f761f1eb]173
[43114c5]174 spinlock_lock(&THREAD->lock);
[8cf8ee6]175 if ((ticks = THREAD->ticks)) {
176 if (ticks >= 1 + missed_clock_ticks)
177 THREAD->ticks -= 1 + missed_clock_ticks;
178 else
179 THREAD->ticks = 0;
180 }
[dbe9ff0]181 spinlock_unlock(&THREAD->lock);
182
183 if (!ticks && !PREEMPTION_DISABLED) {
[f761f1eb]184 scheduler();
185 }
186 }
187
188}
[b45c443]189
[1bb2e7a]190/** @}
[b45c443]191 */
Note: See TracBrowser for help on using the repository browser.