Changeset 619 for trunk/user/ksh/ksh.c


Ignore:
Timestamp:
Feb 12, 2019, 1:15:47 PM (5 years ago)
Author:
alain
Message:

1) Fix a bug in KSH : after the "load" command,

the [ksh] prompt is now printed after completion
of the loaded application.

2) Fix a bug in vmm_handle_cow() : the copy-on-write

use now a hal_remote_memcpy() to replicate the page content.


File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/user/ksh/ksh.c

    r616 r619  
    2121//   the TXT terminal ownership.
    2222//
    23 // We use a semaphore to synchronize the two KSH threads. At each iteration,
    24 // the interactive thread check the semaphore (with a sem_wait). It blocks
    25 // and deschedules, if the KSH process loosed the TXT ownership (after a load,
    26 // or for any other cause. It unblocks with the following policy:
     23// We use a semaphore to synchronize the two KSH threads. After each command
     24// completion, the interactive thread check the TXT ownership (with a sem_wait),
     25// and blocks, if the KSH process loosed the TXT ownership (after a load,
     26// or for any other cause). It is unblocked with the following policy:
    2727// . if the command is "not a load", the semaphore is incremented by the
    28 //   cmd_***() function when the command is completed, to allow the KSH interactive()
    29 //   function to get the next command in the while loop.   
     28//   cmd_***() function when the command is completed, to get the next command
     29//   in the while loop.   
    3030// . if the command is a "load without &", the TXT is given to the NEW process by the
    3131//   execve() syscall, and is released to the KSH process when NEW process terminates.
     
    5656
    5757#define DEBUG_MAIN          0
    58 
     58#define DEBUG_INTER         0
     59#define DEBUG_PARSE         0
    5960#define DEBUG_CMD_CAT       0
    6061#define DEBUG_CMD_CP        0
    6162#define DEBUG_CMD_LOAD      0
    6263#define DEBUG_CMD_LS        0
     64#define DEBUG_CMD_PS        0
    6365
    6466//////////////////////////////////////////////////////////////////////////////////////////
     
    8890//////////////////////////////////////////////////////////////////////////////////////////
    8991
    90 ksh_cmd_t       cmd[];                    // array of supported commands
     92ksh_cmd_t       command[];                // array of supported commands
    9193
    9294log_entry_t     log_entries[LOG_DEPTH];   // array of registered commands
     
    99101sem_t           semaphore;                // block interactive thread when zero
    100102
     103pthread_t       trdid;                    // interactive thread identifier
     104 
    101105//////////////////////////////////////////////////////////////////////////////////////////
    102106//         Shell  Commands
     
    112116    char         * buf;
    113117
     118#if DEBUG_CMD_CAT
     119char string[64];
     120#endif
     121
    114122        if (argc != 2)
    115123    {
     
    134142
    135143#if DEBUG_CMD_CAT
    136 long long unsigned cycle;
    137 get_cycle( &cycle );
    138 printf("\n[%s] file %s open / cycle %d\n",
    139 __FUNCTION__ , path , (int)cycle );
     144snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, path );
     145display_string( string );
    140146#endif
    141147
     
    161167
    162168#if DEBUG_CMD_CAT
    163 get_cycle( &cycle );
    164 printf("\n[%s] get size %d / cycle %d\n",
    165 __FUNCTION__ , size , (int)cycle );
     169snprintf( string , 64 , "[KSH] %s : get size = %d", __FUNCTION__, size );
     170display_string( string );
    166171#endif
    167172
     
    176181
    177182#if DEBUG_CMD_CAT
    178 get_cycle( &cycle );
    179 printf("\n[%s] map file %d to buffer %x / cycle %d\n",
    180 __FUNCTION__ , fd , buf , (int)cycle );
     183snprintf( string , 64 , "[KSH] %s : map file %d to buffer %x", __FUNCTION__, fd , buf );
     184display_string( string );
    181185display_vmm( 0 , getpid() );
    182186#endif
     
    237241        struct stat  st;
    238242
     243#if DEBUG_CMD_CP
     244char string[64];
     245#endif
     246
    239247        if (argc != 3)
    240248    {
     
    259267
    260268#if DEBUG_CMD_CP
    261 long long unsigned cycle;
    262 get_cycle( &cycle );
    263 printf("\n[%s] open file <%s> done / cycle %d\n",
    264 __FUNCTION__ , srcpath , (int)cycle );
     269snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, srcpath );
     270display_string( string );
    265271#endif
    266272
     
    274280
    275281#if DEBUG_CMD_CP
    276 get_cycle( &cycle );
    277 printf("\n[%s] stats file <%s> done / cycle %d\n",
    278 __FUNCTION__ , srcpath , (int)cycle );
     282snprintf( string , 64 , "[KSH] %s : got stats for %s", __FUNCTION__, srcpath );
     283display_string( string );
    279284#endif
    280285
     
    299304
    300305#if DEBUG_CMD_CP
    301 get_cycle( &cycle );
    302 printf("\n[%s] open file <%s> done / cycle %d\n",
    303 __FUNCTION__ , dstpath , (int)cycle );
     306snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, dstpath );
     307display_string( string );
    304308#endif
    305309
     
    311315
    312316#if DEBUG_CMD_CP
    313 get_cycle( &cycle );
    314 printf("\n[%s] stats file <%s> done / cycle %d\n",
    315 __FUNCTION__ , dstpath , (int)cycle );
     317snprintf( string , 64 , "[KSH] %s : got stats for %s", __FUNCTION__, dstpath );
     318display_string( string );
    316319#endif
    317320
     
    336339
    337340#if DEBUG_CMD_CP
    338 get_cycle( &cycle );
    339 printf("\n[%s] %d bytes read from <%s> / cycle %d\n",
    340 __FUNCTION__ , len, srcpath , (int)cycle );
     341snprintf( string , 64 , "[KSH] %s : read %d bytes from %s", __FUNCTION__, len, srcpath );
     342display_string( string );
    341343#endif
    342344
     
    349351
    350352#if DEBUG_CMD_CP
    351 get_cycle( &cycle );
    352 printf("\n[%s] %d bytes writen to <%s> / cycle %d\n",
    353 __FUNCTION__ , len, dstpath , (int)cycle );
     353snprintf( string , 64 , "[KSH] %s : write %d bytes to %s", __FUNCTION__, len, dstpath );
     354display_string( string );
    354355#endif
    355356
     
    573574    else
    574575    {
    575             printf("available commands:\n");
    576             for (i = 0 ; cmd[i].name ; i++)
    577         {
    578                     printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc);
     576        printf("available commands:\n");
     577            for (i = 0 ; command[i].name ; i++)
     578        {
     579                    printf("\t%s\t : %s\n", command[i].name , command[i].desc);
    579580            }
    580581    }
     
    624625    unsigned int         placement;          // placement specified if non zero
    625626    unsigned int         cxy;                // target cluster if placement specified
     627
     628#if DEBUG_CMD_LOAD
     629char string[64];
     630#endif
    626631
    627632        if( (argc < 2) || (argc > 4) ) 
     
    661666        }
    662667
     668/*
     669        // take semaphore to block the interactive thread
     670        if ( sem_wait( &semaphore ) )
     671        {
     672            printf("\n[ksh error] cannot found semafore\n" );
     673            exit( 1 );
     674        }
     675*/
    663676        // get KSH process PID
    664677        ksh_pid = getpid();
    665678
    666679#if DEBUG_CMD_LOAD
    667 long long unsigned cycle;
    668 get_cycle( &cycle );
    669 printf("\n[ksh] %s : ksh_pid %x / path %s / bg %d / place %d (%x) / cycle %d\n",
    670 __FUNCTION__, ksh_pid, argv[1], background, placement, cxy, (int)cycle );
     680snprintf( string , 64 , "[KSH] %s : ksh_pid %x / path %s / bg %d / place %d (%x)\n",
     681__FUNCTION__, ksh_pid, argv[1], background, placement, cxy );
     682display_string( string );
    671683#endif
    672684
     
    685697
    686698#if DEBUG_CMD_LOAD
    687 get_cycle( &cycle );
    688 printf("\n[ksh] %s : child_pid %x after fork, before exec / cycle %d\n",
    689 __FUNCTION__ , getpid(), (int)cycle );
     699snprintf( string , 64 , "[KSH] %s : child_pid %x after fork, before exec\n",
     700__FUNCTION__ , getpid() );
     701display_string( string );
    690702#endif
    691703
     
    694706
    695707#if DEBUG_CMD_LOAD
    696 get_cycle( &cycle );
    697 printf("\n[ksh] %s : child_pid %x after exec / ret_exec %d / cycle %d\n",
    698 __FUNCTION__ , getpid(), ret_exec, (int)cycle );
     708snprintf( string , 64 , "[KSH] %s : child_pid %x after exec / ret_exec %x\n",
     709__FUNCTION__ , getpid(), ret_exec );
     710display_string( string );
    699711#endif
    700712
     
    710722
    711723#if DEBUG_CMD_LOAD
    712 get_cycle( &cycle );
    713 printf("\n[ksh] %s : ksh_pid %x after fork / ret_fork %x / cycle %d\n",
    714 __FUNCTION__, getpid(), ret_fork, (int)cycle );
    715 #endif
    716 
    717             if( background )    // child in background => KSH must keep TXT ownership
     724snprintf( string , 64 , "[KSH] %s : ksh_pid %x after fork / ret_fork %x\n",
     725__FUNCTION__, getpid(), ret_fork );
     726display_string( string );
     727#endif
     728
     729            if( background )    // KSH must keep TXT ownership
    718730            {
     731                // get back the TXT ownership
    719732                fg( ksh_pid );
     733
     734                // release semaphore to get next command
     735                sem_post( &semaphore );
    720736            }
    721         }
    722     }
    723 
    724     // release semaphore to get next command
    725     sem_post( &semaphore );
    726    
     737            else                // KSH loosed TXT ownership
     738            {
     739                // semaphore will be released by the KSH main thread
     740                // when the loaded process exit
     741            }
     742        }
     743    }
    727744}   // end cmd_load
    728745
     
    758775    DIR            * dir;
    759776
     777#if DEBUG_CMD_LS
     778char string[64];
     779#endif
     780
    760781        if (argc > 2 )
    761782    {
     
    774795
    775796#if DEBUG_CMD_LS
    776 printf("\n[ksh] %s : directory <%s> open / DIR %x\n",
     797snprintf( string , 64 , "[KSH] %s : directory <%s> open / DIR %x\n",
    777798__FUNCTION__, pathname , dir );
     799display_string( string );
    778800#endif
    779801
     
    794816
    795817#if DEBUG_CMD_LS
    796 printf("\n[ksh] %s : directory <%s> closed\n",
     818snprintf( string , 64 , "[KSH] %s : directory <%s> closed\n",
    797819__FUNCTION__, pathname );
     820display_string( string );
    798821#endif
    799822
     
    865888    unsigned int y;
    866889
     890#if DEBUG_CMD_PS
     891char string[64];
     892#endif
     893
    867894        if (argc != 1)
    868895    {
     
    879906            for( y = 0 ; y < y_size ; y++ )
    880907            {
     908
     909#if DEBUG_CMD_PS
     910snprintf( string , 64 , "\n[KSH] %s : call display_cluster_process()", __FUNCTION__ );
     911display_string( string );
     912#endif
     913
    881914                // display only owned processes
    882915                display_cluster_processes( HAL_CXY_FROM_XY(x,y), 1 );
     
    10031036///////////////////////////////////////////////////////////////////////////////////
    10041037
    1005 ksh_cmd_t cmd[] =
     1038ksh_cmd_t command[] =
    10061039{
    10071040        { "cat",     "display file content",                            cmd_cat     },
     
    10311064static void __attribute__ ((noinline)) parse( char * buf )
    10321065{
    1033         int argc = 0;
    1034         char *argv[MAX_ARGS];
    1035         int i;
    1036         int len = strlen(buf);
     1066        int    argc = 0;
     1067        char * argv[MAX_ARGS];
     1068        int    i;
     1069        int    len = strlen(buf);
     1070
     1071#if DEBUG_PARSE
     1072char string[64];
     1073snprintf( string , 64 , "\n[KSH] %s : <%s>", __FUNCTION__ , buf );
     1074display_string( string );
     1075#endif
    10371076
    10381077        // build argc/argv
    10391078        for (i = 0; i < len; i++)
    10401079    {
     1080        // convert SPACE to NUL
    10411081                if (buf[i] == ' ')
    10421082        {
     
    10531093        }
    10541094
     1095#if DEBUG_PARSE
     1096snprintf( string , 64 , "\n[KSH] %s : argc = %d for <%s>", __FUNCTION__ , argc , argv[0] );
     1097display_string( string );
     1098#endif
     1099
    10551100    // analyse command type
    10561101        if (argc > 0)
     
    10581103                int found = 0;
    10591104
    1060                 argv[argc] = NULL;
    1061 
    10621105                // try to match typed command
    1063                 for (i = 0 ; cmd[i].name ; i++)
    1064         {
    1065                         if (strcmp(argv[0], cmd[i].name) == 0)
     1106                for ( i = 0 ; command[i].name ; i++ )
     1107        {
     1108                        if (strcmp(argv[0], command[i].name) == 0)
    10661109            {
    1067                                 cmd[i].fn(argc, argv);
     1110                                command[i].fn(argc, argv);
    10681111                                found = 1;
    10691112                                break;
     
    10851128{
    10861129        char           c;                                               // read character
    1087         char           buf[CMD_MAX_SIZE];               // buffer for one command
    10881130    unsigned int   end_command;             // last character found in a command
    10891131        unsigned int   count;                   // pointer in command buffer
     
    10911133        unsigned int   state;                   // escape sequence state
    10921134
     1135        char           cmd[CMD_MAX_SIZE];               // buffer for one command
     1136
     1137#if DEBUG_INTER
     1138char string[64];
     1139#endif
    10931140
    10941141/* To lauch one command without interactive mode
    1095    
    10961142if( sem_wait( &semaphore ) )
    10971143{
     
    11011147else
    11021148{
    1103     printf("\n[ksh] ls bin/user\n");
     1149    printf("\n[ksh] load bin/user/sort.elf\n");
    11041150}
    11051151
    1106 strcpy( buf , "ls bin/user" );
    1107 parse( buf );
    1108 
     1152strcpy( cmd , "load bin/user/sort.elf" );
     1153parse( cmd );
    11091154*/
    11101155
     
    11271172        // - BRAKET : the wo characters (ESC,[) have been found
    11281173
    1129     // external loop on the commands
    1130     // the in teractive thread should not exit this loop
     1174    // take the semaphore for the first command
     1175    if ( sem_wait( &semaphore ) )
     1176    {
     1177        printf("\n[ksh error] cannot found semafore\n" );
     1178        exit( 1 );
     1179    }
     1180
     1181    // display prompt for the first command
     1182    printf("\n[ksh] ");
     1183
     1184    // external loop on the commands / the interactive thread do not exit this loop
    11311185        while (1)
    11321186        {
    11331187            // initialize command buffer
    1134             memset( buf, 0x20 , sizeof(buf) );   // TODO useful ?
    1135             count = 0;
    1136             state = NORMAL;
    1137 
    1138         // decrement semaphore, and block if the KSH process is not the TXT owner
    1139         if ( sem_wait( &semaphore ) )
    1140         {
    1141             printf("\n[ksh error] cannot found semafore\n" );
    1142             exit( 1 );
    1143         }
    1144 
    1145         // display prompt on a new line
    1146         printf("\n[ksh] ");
    1147  
     1188            memset( cmd, 0x20 , sizeof(cmd) );   // TODO useful ?
     1189            count       = 0;
     1190            state       = NORMAL;
    11481191        end_command = 0;
     1192
     1193#if DEBUG_INTER
     1194unsigned int pid = getpid();
     1195snprintf( string , 64 , "\n[KSH] %s : request a new command", __FUNCTION__ );
     1196display_string( string );
     1197#endif
    11491198
    11501199        // internal loop on characters in one command
     
    11711220                                    {
    11721221                                            // complete command with NUL character
    1173                                             buf[count] = 0;
     1222                                            cmd[count] = 0;
    11741223                        count++;
    11751224
    1176                                         // register command in log arrays
    1177                                             strcpy(log_entries[ptw].buf, buf);
     1225                        // register command in log
     1226                                            strncpy( log_entries[ptw].buf , cmd , count );
    11781227                                            log_entries[ptw].count = count;
    11791228                                            ptw = (ptw + 1) % LOG_DEPTH;
    11801229                                            ptr = ptw;
    11811230
     1231#if DEBUG_INTER
     1232snprintf( string , 64 , "[KSH] %s : parse and execute <%s>", __FUNCTION__, cmd );
     1233display_string( string );
     1234#endif
    11821235                        // echo character
    11831236                        putchar( c );
    11841237
    11851238                                            // call parser to analyse and execute command
    1186                                             parse( buf );
     1239                                            parse( cmd );
    11871240                                    }
    11881241                    else                         // no command registered
     
    12041257                            else                                               // normal character
    12051258                                {
    1206                                     if (count < sizeof(buf) - 1)
     1259                                    if (count < (sizeof(cmd) - 1) )
    12071260                                    {
    12081261                        // register character in command buffer
    1209                                             buf[count] = c;
     1262                                            cmd[count] = c;
    12101263                                            count++;
    12111264
     
    12131266                        putchar( c );
    12141267                                        }
     1268                    else
     1269                    {
     1270                                printf("\none command cannot exceed %d characters\n", sizeof(cmd) );
     1271                    }
    12151272                                }
    12161273                        }
     
    12281285                        else if( state == BRAKET )
    12291286                        {
    1230                                 if (c == 'D')   // valid  LEFT sequence => move buf pointer left
     1287                                if (c == 'D')   // valid  LEFT sequence => move cmd pointer left
    12311288                                {
    12321289                                        if (count > 0)
     
    12391296                                        state = NORMAL;
    12401297                                }
    1241                                 else if (c == 'C')   // valid  RIGHT sequence => move buf pointer right
     1298                                else if (c == 'C')   // valid  RIGHT sequence => move cmd pointer right
    12421299                                {
    1243                                         if (count < sizeof(buf) - 1)
     1300                                        if (count < sizeof(cmd) - 1)
    12441301                                        {
    1245                                                 printf("%c", buf[count]);
     1302                                                printf("%c", cmd[count]);
    12461303                                                count++;
    12471304                                        }
     
    12561313                                        count = 0;
    12571314
    1258                                         // copy log command into buf
     1315                                        // copy log command into cmd
    12591316                                        ptr = (ptr - 1) % LOG_DEPTH;
    1260                                         strcpy(buf, log_entries[ptr].buf);
     1317                                        strcpy(cmd, log_entries[ptr].buf);
    12611318                                        count = log_entries[ptr].count - 1;
    12621319
    12631320                                        // display log command
    1264                                         printf("%s", buf);
     1321                                        printf("%s", cmd);
    12651322
    12661323                                        // get next user char
     
    12731330                                        count = 0;
    12741331
    1275                                         // copy log command into buf
     1332                                        // copy log command into cmd
    12761333                                        ptr = (ptr + 1) % LOG_DEPTH;
    1277                                         strcpy(buf, log_entries[ptr].buf);
     1334                                        strcpy(cmd, log_entries[ptr].buf);
    12781335                                        count = log_entries[ptr].count;
    12791336
    12801337                                        // display log command
    1281                                         printf("%s", buf);
     1338                                        printf("%s", cmd);
    12821339
    12831340                                        // get next user char
     
    12911348                        }
    12921349                }  // end internal while loop on characters
     1350
     1351#if DEBUG_INTER
     1352snprintf( string , 64 , "\n[KSH] %s : complete <%s> command", __FUNCTION__, cmd );
     1353display_string( string );
     1354#endif
     1355
     1356        // block interactive thread if KSH loose TXT ownership
     1357        if ( sem_wait( &semaphore ) )
     1358        {
     1359            printf("\n[ksh error] cannot found semafore\n" );
     1360            exit( 1 );
     1361        }
     1362
     1363        // display prompt for next command
     1364        printf("\n[ksh] ");
     1365
    12931366        }  // end external while loop on commands
     1367
    12941368}  // end interactive()
    12951369
     
    13021376    int          child_pid;       // child process identifier
    13031377    int          parent_pid;      // parent process identifier (i.e. this process)
    1304     pthread_t    trdid;           // interactive thread identifier (unused)
    13051378    unsigned int is_owner;        // non-zero if KSH process is TXT owner
    13061379
     
    13151388
    13161389#if DEBUG_MAIN
    1317 printf("\n[ksh] main started on core[%x,%d]\n", cxy , lid );
     1390printf("\n[ksh] main thread started on core[%x,%d]\n", cxy , lid );
    13181391#endif
    13191392   
     
    13391412                    NULL );
    13401413#if DEBUG_MAIN
    1341 printf("\n[ksh] main launched interactive thread => wait children termination\n" );
     1414printf("\n[ksh] main thread launched interactive thread %x\n", trdid );
    13421415#endif
    13431416
     
    13601433        is_fg( parent_pid , &is_owner );
    13611434        if( is_owner ) sem_post( &semaphore );
    1362 
    13631435    }
    13641436}  // end main()
Note: See TracChangeset for help on using the changeset viewer.