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

Last change on this file since 355 was 337, checked in by alain, 7 years ago

Introduce the delayed context switch if current thread has a lock.

File size: 5.6 KB
RevLine 
[1]1/*
2 * core.c - core descriptor access function.
[19]3 *
[1]4 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
[68]5 *         Alain Greiner (2016,2017)
[1]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
[14]25#include <kernel_config.h>
[1]26#include <hal_types.h>
27#include <hal_special.h>
28#include <errno.h>
29#include <printk.h>
30#include <thread.h>
[5]31#include <chdev.h>
[188]32#include <dev_pic.h>
[1]33#include <rpc.h>
34#include <cluster.h>
35#include <kmem.h>
36#include <dqdt.h>
37#include <core.h>
38
39/////////////////////////////////
[19]40void core_init( core_t    * core,
41                lid_t       lid,
[5]42                gid_t       gid )
[1]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;
[19]52        core->thread_idle       = NULL;
53        core->fpu_owner         = NULL;
[126]54        core->rand_last         = hal_time_stamp() & 0xFFF;
[1]55
[188]56    // initialize scheduler
[1]57        sched_init( core );
58}
59
60//////////////////////////////////////////////
61inline uint32_t core_get_rand( core_t * core )
62{
[19]63        uint32_t value  = ((core->rand_last * CONFIG_RDNG_PARAM_A) +
[101]64                            CONFIG_RDNG_PARAM_C) ^ (hal_get_cycles() & 0xFFF);
[19]65        core->rand_last = value;
66        return value;
[1]67}
68
69////////////////////////////////////
70void core_get_time( core_t   * core,
[23]71                    uint32_t * tm_s, 
[1]72                    uint32_t * tm_us )
73{
[101]74        uint64_t cycles = hal_get_cycles();
[1]75
[101]76        *tm_s  = (cycles / CONFIG_CYCLES_PER_MS);
77        *tm_us = (cycles % CONFIG_CYCLES_PER_MS) / (CONFIG_CYCLES_PER_MS / 1000000);
[1]78}
79
80//////////////////////////////////////
81void core_time_update( core_t * core )
82{
[19]83        uint32_t elapsed;
[1]84        uint32_t ticks_nr   = core->ticks_nr;
85        uint64_t cycles     = core->cycles;
86        uint32_t time_stamp = core->time_stamp;
[101]87        uint32_t time_now   = hal_get_cycles();
[1]88
[19]89        // compute number of elapsed cycles taking into account 32 bits register wrap
[1]90        if( time_now < time_stamp ) elapsed = (0xFFFFFFFF - time_stamp) + time_now;
91        else                        elapsed = time_now - time_stamp;
[19]92
[1]93        cycles  += elapsed;
94        ticks_nr = elapsed / core->ticks_period;
95
96        core->time_stamp     = time_now;
97        core->cycles         = cycles + elapsed;
98        core->ticks_nr       = ticks_nr + (elapsed / core->ticks_period);
[124]99        hal_fence();
[1]100}
101
102////////////////////////////////
103void core_clock( core_t * core )
104{
105        uint32_t ticks;
106
[19]107        // update cycles and ticks counter
[1]108        core_time_update( core );
109
[19]110        // get current ticks number
[1]111        ticks = core->ticks_nr;
112
[19]113        // handle pending alarms TODO ??? [AG]
[1]114        // alarm_clock( &core->alarm_mgr , ticks );
115
[19]116        // handle scheduler TODO  improve the scheduling condition ... AG
[296]117        if( (ticks % 10) == 0 ) sched_yield( NULL );
[19]118
[337]119/*
120    // compute elapsed time, taking into account 32 bits register wrap
121    uint32_t elapsed;
122    uint32_t time_now   = hal_get_cycles();
123    uint32_t time_last  = this->time_last_check;
124    if( time_now < time_last ) elapsed = (0xFFFFFFFF - time_last) + time_now;
125        else                       elapsed = time_now - time_last;
126
127    // update thread time
128    this->time_last_check = time_now;
129
130        // check elapsed time
131        if( elapsed < CONFIG_CORE_CHECK_EVERY ) return false;
132    else                                    return true;
133*/
134
[19]135        // update DQDT TODO  This update should depend on the cluster identifier,
136        // to avoid simultaneous updates from various clusters ... AG
[1]137        if( ((ticks % CONFIG_DQDT_PERIOD) == 0) && (core->lid == 0) ) dqdt_global_update();
138}
139
140////////////////////////////////////////
[19]141void core_compute_stats( core_t * core )
[1]142{
143        thread_t * idle  = core->thread_idle;
144        uint32_t   ticks = core->ticks_nr;
145
146        uint32_t   idle_percent;
147        uint32_t   busy_percent;
148        uint32_t   usage;
149
[19]150        // compute cumulated usage
[1]151        ticks         = (ticks) ? ticks : 1;
152        idle_percent  = (idle->ticks_nr * 100) / ticks;
153        idle_percent  = (idle_percent > 100) ? 100 : idle_percent;
154        busy_percent  = 100 - idle_percent;
155        usage         = (busy_percent + core->usage) / 2;
156
[19]157        // update core descriptor
[1]158        core->usage = usage;
[124]159        hal_fence();
[1]160
161#if CONFIG_SHOW_CPU_USAGE
162        printk(INFO, "INFO: core %d in cluster %x : busy_percent = %d / cumulated_usage = %d\n",
163               core->lid, local_cxy , busy_percent , usage );
164#endif
165
166        core->ticks_nr = 0;
167        idle->ticks_nr = 0;
168}
169
170/////////////////////////////////////
171void core_reset_stats( core_t * core )
172{
173        core_time_update(core);
174
175        core->ticks_nr              = 0;
176        core->usage                 = 0;
177        core->thread_idle->ticks_nr = 0;
[124]178        hal_fence();
[1]179}
180
[188]181
182/* deprecated [AG] july 20017
[1]183///////////////////////////////////////////////////
[5]184void core_set_irq_vector_entry( core_t   * core,
[1]185                                uint32_t   irq_type,
186                                uint32_t   irq_id,
[5]187                                chdev_t  * chdev )
[1]188{
[19]189        if     ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev;
190        else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev;
191        else                            core->pti_vector[irq_id] = chdev;
[1]192}
[188]193*/
Note: See TracBrowser for help on using the repository browser.