Ignore:
Timestamp:
Nov 19, 2020, 11:44:34 PM (3 years ago)
Author:
alain
Message:

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:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/alarm.c

    r494 r669  
    11/*
    2  * kern/time.c - thread time related management
    3  *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     2 * alarm.c - timer based kernel alarm implementation           
    63 *
    7  * This file is part of ALMOS-kernel.
     4 * Author     Alain Greiner (2016,2017,2018,2019,2020)
    85 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
    2223
    23 #include <types.h>
     24#include <kernel_config.h>
     25#include <hal_kernel_types.h>
     26#include <printk.h>
     27#include <list.h>
    2428#include <thread.h>
    25 #include <task.h>
    26 #include <scheduler.h>
    27 #include <time.h>
    28 #include <list.h>
    29 #include <rt_timer.h>
    30 #include <kmagics.h>
     29#include <core.h>
     30#include <alarm.h>
    3131
    32 error_t alarm_wait(struct alarm_info_s *info, uint_t msec)
     32////////////////////////////////////////////////////////////////////////////////////////////
     33// This static function registers the alarm identified ny the <new_alarm> argument
     34// in the list of alarms rooted in the core identified by the <core> argument.
     35// When the existing list of alarms is not empty, it scan the list to insert the new
     36// alarm in the right place to respect the absolute dates ordering.
     37////////////////////////////////////////////////////////////////////////////////////////////
     38// @ new_alarm  : local pointer on the new alarm.
     39// @ core       : local pointer on the target core.
     40////////////////////////////////////////////////////////////////////////////////////////////
     41static void alarm_register( alarm_t * new_alarm,
     42                            core_t  * core )
    3343{
    34         register uint_t tm_now;
    35         struct cpu_s *cpu;
    36         struct alarm_s *alarm_mgr;
    37         struct list_entry *iter;
    38         struct alarm_info_s *current;
    39         uint_t irq_state;
     44    list_entry_t * current;          // pointer on current list_entry in existing list
     45    list_entry_t * previous;         // pointer on previous list_entry in existing list
     46    alarm_t      * current_alarm;    // pointer on current alarm in existing list
     47    cycle_t        current_date;     // date of current alarm in existing list
    4048
    41         cpu       = current_cpu;
    42         alarm_mgr = &cpu->alarm_mgr;
     49    bool_t         done = false;
    4350
    44         cpu_disable_all_irq(&irq_state);
     51    // get pointers on root of alarms and lock
     52    list_entry_t * root = &core->alarms_root;
     53    busylock_t   * lock = &core->alarms_lock;
    4554
    46         tm_now          = cpu_get_ticks(cpu) * MSEC_PER_TICK;
    47         info->signature = ALRM_INFO_ID;
    48         info->tm_wakeup = tm_now + msec;
     55    // get pointer on new_alarm list_entry
     56    list_entry_t * new_entry = &new_alarm->list;
    4957
    50         if(list_empty(&alarm_mgr->wait_queue))
    51                 list_add_first(&alarm_mgr->wait_queue, &info->list);
    52         else
    53         {
    54                 list_foreach_forward(&alarm_mgr->wait_queue, iter)
    55                 {
    56                         current = list_element(iter, struct alarm_info_s, list);
    57      
    58                         if(info->tm_wakeup <= current->tm_wakeup)
    59                         {
    60                                 list_add_pred(iter, &info->list);
    61                                 goto NEXT_TRAITMENT;
    62                         }
    63                 }
    64                 list_add_last(&alarm_mgr->wait_queue, &info->list);
    65         }
     58    // get new_alarm date
     59    cycle_t        new_date = new_alarm->date;
    6660
    67 NEXT_TRAITMENT:
    68         cpu_restore_irq(irq_state);
    69         return 0;
    70 }
     61    // take the lock
     62    busylock_acquire( lock );
    7163
    72 void alarm_clock(struct alarm_s *alarm, uint_t ticks_nr)
     64    // insert new alarm to respect dates order
     65    if( list_is_empty( root ) )                     // list empty
     66    {
     67        list_add_first( root , new_entry );
     68    }
     69    else                                            // list non empty
     70    {
     71        for( current = root->next ;
     72             (current != root) && (done == false) ;
     73             current = current->next )
     74        {
     75            // get pointer on previous entry in existing list
     76            previous = current->pred;
     77
     78            // get pointer on current alarm
     79            current_alarm = LIST_ELEMENT( current , alarm_t , list );
     80
     81            // get date for current alarm
     82            current_date  = current_alarm->date;
     83
     84            if( current_date > new_date )  // insert new alarm just before current
     85            {
     86                new_entry->next = current;
     87                new_entry->pred = previous;
     88
     89                current->pred  = new_entry;
     90                previous->next = new_entry;
     91               
     92                done = true;
     93            }
     94        }  // end for
     95       
     96        if( done == false ) // new_date is larger than all registered dates
     97        {
     98            list_add_last( root , new_entry );
     99        }
     100    }
     101
     102    // release the lock
     103    busylock_release( lock );
     104
     105}  // end alarm_register()
     106
     107//////////////////////////////////////
     108void alarm_start( cycle_t    date,
     109                  void     * func_ptr,
     110                  xptr_t     args_xp,
     111                  thread_t * thread )
    73112{
    74         register uint_t tm_msec;
    75         register struct list_entry *iter;
    76         register struct alarm_info_s *info;
    77  
    78         tm_msec = ticks_nr * MSEC_PER_TICK;
     113    // get pointer on alarm
     114    alarm_t * alarm = &thread->alarm;
    79115
    80         list_foreach_forward(&alarm->wait_queue, iter)
    81         {
    82                 info = list_element(iter, struct alarm_info_s, list);
     116    // initialize alarm descriptor
     117    alarm->date     = date;
     118    alarm->func_ptr = func_ptr;
     119    alarm->args_xp = args_xp;
     120   
     121    // register alarm in core list
     122    alarm_register( alarm , thread->core );
    83123
    84                 assert((info->signature == ALRM_INFO_ID), "Not an ALRM info object");
     124}  // end alarm_start()
    85125
    86                 if(tm_msec < info->tm_wakeup)
    87                         break;
     126/////////////////////////////////////
     127void alarm_update( thread_t * thread,
     128                   cycle_t    new_date )
     129{
     130    // get pointer on alarm
     131    alarm_t * alarm = &thread->alarm;
     132
     133    // get pointer on core
     134    core_t   * core = thread->core;
     135
     136    // get pointer on lock protecting the alarms list
     137    busylock_t   * lock = &core->alarms_lock;
     138
     139    // unlink the alarm from the core list
     140    busylock_acquire( lock );
     141    list_unlink( &alarm->list );
     142    busylock_release( lock );
     143
     144    // update the alarm date
     145    alarm->date = new_date;
     146
     147    // register alarm in core list
     148    alarm_register( alarm , core );
    88149   
    89                 list_unlink(iter);
    90                 event_send(info->event, current_cpu->gid);
    91         }
    92 }
     150}  // end alarm_update()
    93151
    94 error_t alarm_manager_init(struct alarm_s *alarm)
     152////////////////////////////////////
     153void alarm_stop( thread_t * thread )
    95154{
    96         list_root_init(&alarm->wait_queue);
    97         return 0;
    98 }
     155    // get pointer on alarm
     156    alarm_t * alarm = &thread->alarm;
    99157
     158    // get pointer on core
     159    core_t * core = thread->core;
    100160
    101 #if CONFIG_THREAD_TIME_STAT
     161    // get pointer on lock protecting the alarms list
     162    busylock_t * lock = &core->alarms_lock;
    102163
    103 inline void tm_sleep_compute(struct thread_s *thread)
    104 {
    105         uint_t tm_now;
     164    // unlink the alarm from the list rooted in core
     165    busylock_acquire( lock );
     166    list_unlink( &alarm->list );
     167    busylock_release( lock );
    106168
    107         if(thread->type == TH_IDLE)
    108                 return;
     169}  // end alarm_stop()
    109170
    110         rt_timer_read(&tm_now);
    111         thread->info.tm_sleep += (tm_now - thread->info.tm_tmp);
    112         thread->info.tm_tmp    = tm_now;
    113 }
    114 
    115 inline void tm_usr_compute(struct thread_s *thread)
    116 {
    117         uint_t tm_now;
    118 
    119         rt_timer_read(&tm_now);
    120         thread->info.tm_usr += (tm_now - thread->info.tm_tmp);
    121         thread->info.tm_tmp  = tm_now;
    122 }
    123 
    124 inline void tm_sys_compute(struct thread_s *thread)
    125 {
    126         uint_t tm_now;
    127 
    128         rt_timer_read(&tm_now);
    129         thread->info.tm_sys += (tm_now - thread->info.tm_tmp);
    130         thread->info.tm_tmp  = tm_now;
    131 }
    132 
    133 inline void tm_wait_compute(struct thread_s *thread)
    134 {
    135         uint_t tm_now;
    136 
    137         if(thread->type == TH_IDLE)
    138                 return;
    139 
    140         rt_timer_read(&tm_now);
    141         thread->info.tm_wait += (tm_now - thread->info.tm_tmp);
    142         thread->info.tm_tmp   = tm_now;
    143         thread->info.tm_exec  = tm_now;
    144 }
    145 
    146 inline void tm_exit_compute(struct thread_s *thread)
    147 {
    148         uint_t tm_now;
    149  
    150         rt_timer_read(&tm_now);
    151         thread->info.tm_sys += tm_now - thread->info.tm_tmp;
    152         thread->info.tm_dead = tm_now;
    153 }
    154 
    155 inline void tm_born_compute(struct thread_s *thread)
    156 {
    157         uint_t tm_now;
    158  
    159         rt_timer_read(&tm_now);
    160         thread->info.tm_born = tm_now;
    161         thread->info.tm_tmp  = tm_now;
    162         thread->info.tm_exec = tm_now;
    163 }
    164 
    165 inline void tm_create_compute(struct thread_s *thread)
    166 {
    167         rt_timer_read(&thread->info.tm_create);
    168 }
    169 
    170 
    171 #endif  /* CONFIG_THREAD_TIME_STAT */
Note: See TracChangeset for help on using the changeset viewer.