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

Last change on this file since 675 was 669, checked in by alain, 4 years ago

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File size: 4.6 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,2018)
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_kernel_types.h>
27#include <hal_special.h>
28#include <printk.h>
29#include <thread.h>
30#include <chdev.h>
31#include <alarm.h>
32#include <dev_pic.h>
33#include <rpc.h>
34#include <cluster.h>
35#include <kmem.h>
36#include <core.h>
37
38/////////////////////////////////
39void core_init( core_t    * core,
40                lid_t       lid,
41                gid_t       gid )
42{
43        core->lid               = lid;
44        core->gid               = gid;
45        core->cycles            = 0;
46        core->time_stamp        = 0;
47        core->ticks_nr          = 0;
48        core->usage             = 0;
49        core->spurious_irqs     = 0;
50        core->fpu_owner         = NULL;
51        core->rand_last         = hal_time_stamp() & 0xFFF;
52
53    // initialize the scheduler
54        sched_init( core );
55
56    // initialise the alarms lock
57    busylock_init( &core->alarms_lock , LOCK_CORE_ALARMS );
58
59    // initialise the alarms list
60    list_root_init( &core->alarms_root );
61}
62
63///////////////////////////////////////
64void core_check_alarms( core_t * core )
65{
66    alarm_handler_t * handler;
67
68    // get pointer on root of alarms list
69    list_entry_t * root = &core->alarms_root;
70
71    // does nothing if list is empty
72    if( list_is_empty( root ) ) return;
73
74    // get pointer on first alarm when list non empty
75    alarm_t * alarm = LIST_FIRST( root , alarm_t , list );
76
77    // get first alarm date
78    cycle_t alarm_date = alarm->date; 
79
80    // get current date
81    cycle_t current_date = hal_get_cycles();
82
83    if( current_date >= alarm_date )
84    {
85        // get pointer on registered alarm handler
86        handler = (alarm_handler_t *)alarm->func_ptr;
87
88        // call alarm handler
89        handler( alarm->args_xp );
90    }
91}   // end core_check_alarms()
92
93//////////////////////
94lid_t core_lid( void )
95{
96    uint32_t    i;
97
98    // get pointer on local cluser descriptor
99    cluster_t * cluster = LOCAL_CLUSTER;
100
101    // get core gid from hardware register
102    gid_t gid = hal_get_gid();
103
104    // makes an associative search in core_tbl[] from gid
105    for( i = 0 ; i < cluster->cores_nr ; i++ )
106    {
107        if( gid == cluster->core_tbl[i].gid ) return i;
108    }
109
110    assert( __FUNCTION__, false , "core not found" );
111
112    return 0;
113}
114
115//////////////////////////////////////////////
116inline uint32_t core_get_rand( core_t * core )
117{
118        uint32_t value  = ((core->rand_last * CONFIG_RDNG_PARAM_A) +
119                            CONFIG_RDNG_PARAM_C) ^ (hal_get_cycles() & 0xFFF);
120        core->rand_last = value;
121        return value;
122}
123
124////////////////////////////////////
125void core_get_time( core_t   * core,
126                    uint32_t * tm_s, 
127                    uint32_t * tm_us )
128{
129        *tm_s  = (core->ticks_nr*CONFIG_SCHED_TICK_MS_PERIOD)/1000;
130        *tm_us = (core->ticks_nr*CONFIG_SCHED_TICK_MS_PERIOD*1000)%1000000;
131}
132
133////////////////////////////////
134void core_clock( core_t * core )
135{
136        uint32_t ticks;
137
138        // update ticks counter
139        ticks = core->ticks_nr++;
140
141        // handle scheduler
142        if( (ticks % CONFIG_SCHED_TICKS_PER_QUANTUM) == 0 ) sched_yield( "TICK");
143
144    // handle alarms
145    core_check_alarms( core );
146}
147
148////////////////////////////////////////
149void core_compute_stats( core_t * core )
150{
151        thread_t * idle  = core->scheduler.idle;
152        uint32_t   ticks = core->ticks_nr;
153
154        uint32_t   idle_percent;
155        uint32_t   busy_percent;
156        uint32_t   usage;
157
158        // compute cumulated usage
159        ticks         = (ticks) ? ticks : 1;
160        idle_percent  = (idle->ticks_nr * 100) / ticks;
161        idle_percent  = (idle_percent > 100) ? 100 : idle_percent;
162        busy_percent  = 100 - idle_percent;
163        usage         = (busy_percent + core->usage) / 2;
164
165        // update core descriptor
166        core->usage = usage;
167        hal_fence();
168
169        core->ticks_nr = 0;
170        idle->ticks_nr = 0;
171}
172
173/////////////////////////////////////
174void core_reset_stats( core_t * core )
175{
176        thread_t * idle  = core->scheduler.idle;
177
178        core->ticks_nr = 0;
179        core->usage    = 0;
180        idle->ticks_nr = 0;
181
182        hal_fence();
183}
184
Note: See TracBrowser for help on using the repository browser.