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

Last change on this file since 630 was 625, checked in by alain, 6 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
Line 
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.
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.
11// It includes the hard_config.h file to get th NB_TXT_CHANNELS parameter.
12///////////////////////////////////////////////////////////////////////////////////////
13
14#include <hard_config.h>
15#include <unistd.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <pthread.h>
19#include <almosmkh.h>
20#include <hal_macros.h>
21#include <sys/wait.h>
22
23#define DEBUG_PROCESS_INIT    0
24
25// TODO improve the get_config() syscall to return nb_txt_channels
26// and avoid the hard_config include [AG]
27
28////////////////
29int main( void )
30{
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
37
38#if DEBUG_PROCESS_INIT
39display_string("[init] process enters");
40#endif
41
42    // check number of TXT channels
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    }
48
49    // create the KSH processes (one per user terminal)
50    for( i = 1 ; i <  NB_TXT_CHANNELS ; i++ )
51    {
52        // INIT process fork process CHILD[i]
53        ret_fork = fork();
54
55        if( ret_fork < 0 )   // error in fork
56        {
57            // INIT display error message 
58            snprintf( string , 64 , "[init ERROR] cannot fork child[%d] => suicide" , i );
59            display_string( string );
60
61            // INIT suicide
62            exit( 0 );
63        }
64        else if( ret_fork == 0 )                    // we are in CHILD[i] process
65        {
66            // CHILD[i] process exec process KSH[i]
67            ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL ); 
68
69            if ( ret_exec )   // error in exec             
70            {
71                // CHILD[i] display error message
72                snprintf( string , 64 , 
73                "[init ERROR] CHILD[%d] cannot exec KSH / ret_exec = %d" , i , ret_exec );
74                display_string( string );
75            }
76        }
77        else                                      // we are in INIT process
78        {
79            // INIT display CHILD[i] process PID
80            snprintf( string , 64 , "[init] (pid 0x1) created ksh[%d] (pid %x)", i , ret_fork ); 
81            display_string( string );
82
83            // wait signal from KSH[i]
84            pause();
85        }
86    } 
87 
88#if DEBUG_PROCESS_INIT
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
97
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++ )
103    {
104        for( y = 0 ; y < y_size ; y++ )
105        {
106            cxy = HAL_CXY_FROM_XY( x , y );
107            display_cluster_processes( cxy );
108            for( lid = 0 ; lid < ncores ; lid++ )
109            { 
110                display_sched( cxy , lid );
111            }
112        }
113    }
114}
115#endif
116
117    // This loop detects the termination of the KSH[i] processes,
118    // and recreate a new KSH[i] process when required.
119    while( 1 )
120    {
121        // block on child processes termination
122        rcv_pid = wait( &status );
123
124        if( WIFSTOPPED( status ) )                         // stopped => unblock it
125        {
126            // display string to report unexpected KSH process block
127            snprintf( string , 64 , "[init] KSH process %x stopped => unblock it" , rcv_pid );
128            display_string( string ); 
129
130            // TODO : unblock KSH [AG]
131
132        }  // end KSH stopped handling
133
134        if( WIFSIGNALED( status ) || WIFEXITED( status ) )  // killed => recreate it
135        {
136            // display string to report KSH process termination
137            snprintf( string , 64 , "[init] KSH process %x terminated => recreate", rcv_pid );
138            display_string( string ); 
139
140            // INIT process fork a new CHILD process
141            ret_fork = fork();
142
143            if( ret_fork < 0 )                          // error in fork
144            {
145                // INIT display error message
146                snprintf( string , 64 , "[init ERROR] cannot fork child => suicide");
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
155                ret_exec = execve( "/bin/user/ksh.elf" , NULL , NULL ); 
156
157                if ( ret_exec )   // error in exec             
158                {
159                    // CHILD display error message on TXT0 terminal
160                    snprintf( string , 64 , "[init ERROR] CHILD cannot exec KSH" );
161                    display_string( string );
162                }
163            }
164            else                                       // we are in INIT process
165            {
166                // INIT display new KSH process PID
167                snprintf( string , 64 , "[init] re-created KSH / pid = %x", ret_fork ); 
168                display_string( string );
169            }
170        } // end KSH kill handling
171
172    }  // end while waiting KSH[i] termination
173
174} // end main()
175
Note: See TracBrowser for help on using the repository browser.