source: trunk/kernel/kern/core.c @ 77

Last change on this file since 77 was 68, checked in by alain, 7 years ago

Fix bug in kernel_init, and reduce size of remote_fifo.

File size: 5.8 KB
Line 
1/*
2 * core.c - core descriptor access function.
3 *
4 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *         Alain Greiner (2016,2017)
6 *
7 * Copyright (c) UPMC Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH.is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#include <kernel_config.h>
26#include <hal_types.h>
27#include <hal_special.h>
28#include <errno.h>
29#include <printk.h>
30#include <thread.h>
31#include <chdev.h>
32#include <dev_icu.h>
33#include <rpc.h>
34#include <cluster.h>
35#include <kmem.h>
36#include <dqdt.h>
37#include <core.h>
38
39/////////////////////////////////
40void core_init( core_t    * core,
41                lid_t       lid,
42                gid_t       gid )
43{
44        core->lid               = lid;
45        core->gid               = gid;
46        core->cycles            = 0;
47        core->time_stamp        = 0;
48        core->ticks_nr          = 0;
49        core->ticks_period      = CONFIG_SCHED_TICK_PERIOD;
50        core->usage             = 0;
51        core->spurious_irqs     = 0;
52        core->rpc_threads       = 0;
53
54        list_root_init( &core->rpc_free_list );
55
56        core->thread_rpc        = NULL;
57        core->thread_idle       = NULL;
58        core->fpu_owner         = NULL;
59        core->rand_last         =  hal_time_stamp() & 0xFFF;
60
61        sched_init( core );
62}
63
64//////////////////////////////////////////////
65inline uint32_t core_get_rand( core_t * core )
66{
67        uint32_t value  = ((core->rand_last * CONFIG_RDNG_PARAM_A) +
68                            CONFIG_RDNG_PARAM_C) ^ (hal_time_stamp() & 0xFFF);
69        core->rand_last = value;
70        return value;
71}
72
73////////////////////////////////////////////////
74inline uint64_t core_get_cycles( core_t * core )
75{
76        uint32_t elapsed;
77        uint64_t cycles;
78        uint32_t time_stamp = core->time_stamp;
79        uint32_t time_now   = hal_time_stamp();
80
81        // compute number of elapsed cycles, taking into account 32 bits register wrap
82        if(time_now < time_stamp) elapsed = (0xFFFFFFFF - time_stamp) + time_now;
83        else                      elapsed = (time_now - time_stamp);
84
85        cycles = core->cycles + elapsed;
86
87        // update core time
88        core->time_stamp = time_now;
89        core->cycles     = cycles;
90        hal_wbflush();
91
92        return cycles;
93}
94
95////////////////////////////////////
96void core_get_time( core_t   * core,
97                    uint32_t * tm_s, 
98                    uint32_t * tm_us )
99{
100        // uint64_t cycles = core_get_cycles( core );
101
102        // TODO ces deux ligne ne compilent pas : "undefined referenc to __udivdi3"
103
104        // *tm_ms = (cycles / CONFIG_CYCLES_PER_MS);
105        // *tm_us = (cycles % CONFIG_CYCLES_PER_MS) / (CONFIG_CYCLES_PER_MS / 1000000);
106
107        printk("\n[PANIC] in %s : not implemented yet\n", __FUNCTION__ );
108}
109
110//////////////////////////////////////
111void core_time_update( core_t * core )
112{
113        uint32_t elapsed;
114        uint32_t ticks_nr   = core->ticks_nr;
115        uint64_t cycles     = core->cycles;
116        uint32_t time_stamp = core->time_stamp;
117        uint32_t time_now   = hal_time_stamp();
118
119        // compute number of elapsed cycles taking into account 32 bits register wrap
120        if( time_now < time_stamp ) elapsed = (0xFFFFFFFF - time_stamp) + time_now;
121        else                        elapsed = time_now - time_stamp;
122
123        cycles  += elapsed;
124        ticks_nr = elapsed / core->ticks_period;
125
126        core->time_stamp     = time_now;
127        core->cycles         = cycles + elapsed;
128        core->ticks_nr       = ticks_nr + (elapsed / core->ticks_period);
129        hal_wbflush();
130}
131
132////////////////////////////////
133void core_clock( core_t * core )
134{
135        uint32_t ticks;
136
137        // update cycles and ticks counter
138        core_time_update( core );
139
140        // get current ticks number
141        ticks = core->ticks_nr;
142
143        // handle pending alarms TODO ??? [AG]
144        // alarm_clock( &core->alarm_mgr , ticks );
145
146        // handle scheduler TODO  improve the scheduling condition ... AG
147        if( (ticks % 10) == 0 ) sched_yield();
148
149        // update DQDT TODO  This update should depend on the cluster identifier,
150        // to avoid simultaneous updates from various clusters ... AG
151        if( ((ticks % CONFIG_DQDT_PERIOD) == 0) && (core->lid == 0) ) dqdt_global_update();
152}
153
154////////////////////////////////////////
155void core_compute_stats( core_t * core )
156{
157        thread_t * idle  = core->thread_idle;
158        uint32_t   ticks = core->ticks_nr;
159
160        uint32_t   idle_percent;
161        uint32_t   busy_percent;
162        uint32_t   usage;
163
164        // compute cumulated usage
165        ticks         = (ticks) ? ticks : 1;
166        idle_percent  = (idle->ticks_nr * 100) / ticks;
167        idle_percent  = (idle_percent > 100) ? 100 : idle_percent;
168        busy_percent  = 100 - idle_percent;
169        usage         = (busy_percent + core->usage) / 2;
170
171        // update core descriptor
172        core->usage = usage;
173        hal_wbflush();
174
175#if CONFIG_SHOW_CPU_USAGE
176        printk(INFO, "INFO: core %d in cluster %x : busy_percent = %d / cumulated_usage = %d\n",
177               core->lid, local_cxy , busy_percent , usage );
178#endif
179
180        core->ticks_nr = 0;
181        idle->ticks_nr = 0;
182}
183
184/////////////////////////////////////
185void core_reset_stats( core_t * core )
186{
187        core_time_update(core);
188
189        core->ticks_nr              = 0;
190        core->usage                 = 0;
191        core->thread_idle->ticks_nr = 0;
192        hal_wbflush();
193}
194
195///////////////////////////////////////////////////
196void core_set_irq_vector_entry( core_t   * core,
197                                uint32_t   irq_type,
198                                uint32_t   irq_id,
199                                chdev_t  * chdev )
200{
201        if     ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev;
202        else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev;
203        else                            core->pti_vector[irq_id] = chdev;
204}
Note: See TracBrowser for help on using the repository browser.