source: trunk/user/init/init.c @ 625

Last change on this file since 625 was 625, checked in by alain, 5 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 6.1 KB
RevLine 
[427]1///////////////////////////////////////////////////////////////////////////////////////
2// File   :  init.c
3// Date   :  January 2018
4// Author :  Alain Greiner
5///////////////////////////////////////////////////////////////////////////////////////
6// This single thread application implement the "init" process for ALMOS-MKH.
[434]7// It uses the fork/exec syscalls to create N KSH child processes
8// (one child process per user terminal).
9// Then calls the wait() function to block, and reactivate any child KSH process
10// that has been deleted, using a new fork/exec.
[440]11// It includes the hard_config.h file to get th NB_TXT_CHANNELS parameter.
[427]12///////////////////////////////////////////////////////////////////////////////////////
13
14#include <hard_config.h>
[444]15#include <unistd.h>
[427]16#include <stdlib.h>
17#include <stdio.h>
18#include <pthread.h>
[445]19#include <almosmkh.h>
[574]20#include <hal_macros.h>
[444]21#include <sys/wait.h>
[427]22
[588]23#define DEBUG_PROCESS_INIT    0
[440]24
[445]25// TODO improve the get_config() syscall to return nb_txt_channels
26// and avoid the hard_config include [AG]
27
[574]28////////////////
[475]29int main( void )
[427]30{
[438]31    int           i;
32    int           ret_fork;      // fork return value 
33    int           ret_exec;      // exec return value 
34    int           rcv_pid;       // pid received from the wait syscall
35    int           status;        // used by the wait syscall
36    char          string[64];    // log messages on kernel TXT0
[427]37
[574]38#if DEBUG_PROCESS_INIT
[623]39display_string("[init] process enters");
[574]40#endif
41
[427]42    // check number of TXT channels
[445]43    if( NB_TXT_CHANNELS < 2 )
44    {
45        printf("\n[ERROR] in init process : number of TXT channels must be larger than 1\n");
46        exit( EXIT_FAILURE );
47    }
[427]48
49    // create the KSH processes (one per user terminal)
[434]50    for( i = 1 ; i <  NB_TXT_CHANNELS ; i++ )
[427]51    {
[434]52        // INIT process fork process CHILD[i]
53        ret_fork = fork();
54
[436]55        if( ret_fork < 0 )   // error in fork
[427]56        {
[437]57            // INIT display error message 
[623]58            snprintf( string , 64 , "[init ERROR] cannot fork child[%d] => suicide" , i );
[427]59            display_string( string );
60
[436]61            // INIT suicide
[434]62            exit( 0 );
[427]63        }
[434]64        else if( ret_fork == 0 )                    // we are in CHILD[i] process
[427]65        {
[434]66            // CHILD[i] process exec process KSH[i]
[444]67            ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL ); 
[434]68
69            if ( ret_exec )   // error in exec             
[427]70            {
[437]71                // CHILD[i] display error message
[435]72                snprintf( string , 64 , 
[623]73                "[init ERROR] CHILD[%d] cannot exec KSH / ret_exec = %d" , i , ret_exec );
[434]74                display_string( string );
[427]75            }
76        }
[434]77        else                                      // we are in INIT process
78        {
[457]79            // INIT display CHILD[i] process PID
[625]80            snprintf( string , 64 , "[init] (pid 0x1) created ksh[%d] (pid %x)", i , ret_fork ); 
[457]81            display_string( string );
[588]82
83            // wait signal from KSH[i]
84            pause();
[434]85        }
86    } 
[440]87 
[442]88#if DEBUG_PROCESS_INIT
[528]89{
90    unsigned int  x_size;        // number of clusters in a row
91    unsigned int  y_size;        // number of clusters in a column
92    unsigned int  ncores;        // number of cores per cluster
93    unsigned int  x;             // cluster x coordinate
94    unsigned int  y;             // cluster y coordinate
95    unsigned int  cxy;           // cluster identifier
96    unsigned int  lid;           // core local index
[434]97
[528]98    // get hardware config
99    get_config( &x_size , &y_size , &ncores );
100
101    // INIT displays processes and threads in all clusters
102    for( x = 0 ; x < x_size ; x++ )
[440]103    {
[588]104        for( y = 0 ; y < y_size ; y++ )
[581]105        {
106            cxy = HAL_CXY_FROM_XY( x , y );
[528]107            display_cluster_processes( cxy );
[581]108            for( lid = 0 ; lid < ncores ; lid++ )
109            { 
110                display_sched( cxy , lid );
111            }
[440]112        }
113    }
[457]114}
[440]115#endif
116
[435]117    // This loop detects the termination of the KSH[i] processes,
[436]118    // and recreate a new KSH[i] process when required.
[427]119    while( 1 )
120    {
[435]121        // block on child processes termination
[436]122        rcv_pid = wait( &status );
[427]123
[435]124        if( WIFSTOPPED( status ) )                         // stopped => unblock it
125        {
126            // display string to report unexpected KSH process block
[623]127            snprintf( string , 64 , "[init] KSH process %x stopped => unblock it" , rcv_pid );
[435]128            display_string( string ); 
129
[440]130            // TODO : unblock KSH [AG]
[435]131
[436]132        }  // end KSH stopped handling
133
[435]134        if( WIFSIGNALED( status ) || WIFEXITED( status ) )  // killed => recreate it
135        {
[437]136            // display string to report KSH process termination
[623]137            snprintf( string , 64 , "[init] KSH process %x terminated => recreate", rcv_pid );
[435]138            display_string( string ); 
[436]139
140            // INIT process fork a new CHILD process
141            ret_fork = fork();
142
143            if( ret_fork < 0 )                          // error in fork
144            {
[437]145                // INIT display error message
[623]146                snprintf( string , 64 , "[init ERROR] cannot fork child => suicide");
[436]147                display_string( string );
148
149                // INIT suicide
150                exit( 0 );
151            }
152            else if( ret_fork == 0 )                    // we are in CHILD process
153            {
154                // CHILD process exec process KSH
[444]155                ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL ); 
[436]156
157                if ( ret_exec )   // error in exec             
158                {
159                    // CHILD display error message on TXT0 terminal
[623]160                    snprintf( string , 64 , "[init ERROR] CHILD cannot exec KSH" );
[436]161                    display_string( string );
162                }
163            }
164            else                                       // we are in INIT process
165            {
[442]166                // INIT display new KSH process PID
[623]167                snprintf( string , 64 , "[init] re-created KSH / pid = %x", ret_fork ); 
[436]168                display_string( string );
169            }
[438]170        } // end KSH kill handling
[427]171
[438]172    }  // end while waiting KSH[i] termination
173
[427]174} // end main()
175
Note: See TracBrowser for help on using the repository browser.