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

Last change on this file since 668 was 659, checked in by alain, 4 years ago

euh...

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