Changeset 619 for trunk/user/ksh
- Timestamp:
- Feb 12, 2019, 1:15:47 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/user/ksh/ksh.c
r616 r619 21 21 // the TXT terminal ownership. 22 22 // 23 // We use a semaphore to synchronize the two KSH threads. A t each iteration,24 // the interactive thread check the semaphore (with a sem_wait). It blocks25 // and deschedules, if the KSH process loosed the TXT ownership (after a load,26 // or for any other cause . It unblockswith 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: 27 27 // . 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 commandin the while loop.28 // cmd_***() function when the command is completed, to get the next command 29 // in the while loop. 30 30 // . if the command is a "load without &", the TXT is given to the NEW process by the 31 31 // execve() syscall, and is released to the KSH process when NEW process terminates. … … 56 56 57 57 #define DEBUG_MAIN 0 58 58 #define DEBUG_INTER 0 59 #define DEBUG_PARSE 0 59 60 #define DEBUG_CMD_CAT 0 60 61 #define DEBUG_CMD_CP 0 61 62 #define DEBUG_CMD_LOAD 0 62 63 #define DEBUG_CMD_LS 0 64 #define DEBUG_CMD_PS 0 63 65 64 66 ////////////////////////////////////////////////////////////////////////////////////////// … … 88 90 ////////////////////////////////////////////////////////////////////////////////////////// 89 91 90 ksh_cmd_t c md[];// array of supported commands92 ksh_cmd_t command[]; // array of supported commands 91 93 92 94 log_entry_t log_entries[LOG_DEPTH]; // array of registered commands … … 99 101 sem_t semaphore; // block interactive thread when zero 100 102 103 pthread_t trdid; // interactive thread identifier 104 101 105 ////////////////////////////////////////////////////////////////////////////////////////// 102 106 // Shell Commands … … 112 116 char * buf; 113 117 118 #if DEBUG_CMD_CAT 119 char string[64]; 120 #endif 121 114 122 if (argc != 2) 115 123 { … … 134 142 135 143 #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 ); 144 snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, path ); 145 display_string( string ); 140 146 #endif 141 147 … … 161 167 162 168 #if DEBUG_CMD_CAT 163 get_cycle( &cycle ); 164 printf("\n[%s] get size %d / cycle %d\n", 165 __FUNCTION__ , size , (int)cycle ); 169 snprintf( string , 64 , "[KSH] %s : get size = %d", __FUNCTION__, size ); 170 display_string( string ); 166 171 #endif 167 172 … … 176 181 177 182 #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 ); 183 snprintf( string , 64 , "[KSH] %s : map file %d to buffer %x", __FUNCTION__, fd , buf ); 184 display_string( string ); 181 185 display_vmm( 0 , getpid() ); 182 186 #endif … … 237 241 struct stat st; 238 242 243 #if DEBUG_CMD_CP 244 char string[64]; 245 #endif 246 239 247 if (argc != 3) 240 248 { … … 259 267 260 268 #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 ); 269 snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, srcpath ); 270 display_string( string ); 265 271 #endif 266 272 … … 274 280 275 281 #if DEBUG_CMD_CP 276 get_cycle( &cycle ); 277 printf("\n[%s] stats file <%s> done / cycle %d\n", 278 __FUNCTION__ , srcpath , (int)cycle ); 282 snprintf( string , 64 , "[KSH] %s : got stats for %s", __FUNCTION__, srcpath ); 283 display_string( string ); 279 284 #endif 280 285 … … 299 304 300 305 #if DEBUG_CMD_CP 301 get_cycle( &cycle ); 302 printf("\n[%s] open file <%s> done / cycle %d\n", 303 __FUNCTION__ , dstpath , (int)cycle ); 306 snprintf( string , 64 , "[KSH] %s : file %s open", __FUNCTION__, dstpath ); 307 display_string( string ); 304 308 #endif 305 309 … … 311 315 312 316 #if DEBUG_CMD_CP 313 get_cycle( &cycle ); 314 printf("\n[%s] stats file <%s> done / cycle %d\n", 315 __FUNCTION__ , dstpath , (int)cycle ); 317 snprintf( string , 64 , "[KSH] %s : got stats for %s", __FUNCTION__, dstpath ); 318 display_string( string ); 316 319 #endif 317 320 … … 336 339 337 340 #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 ); 341 snprintf( string , 64 , "[KSH] %s : read %d bytes from %s", __FUNCTION__, len, srcpath ); 342 display_string( string ); 341 343 #endif 342 344 … … 349 351 350 352 #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 ); 353 snprintf( string , 64 , "[KSH] %s : write %d bytes to %s", __FUNCTION__, len, dstpath ); 354 display_string( string ); 354 355 #endif 355 356 … … 573 574 else 574 575 { 575 576 for (i = 0 ; c md[i].name ; i++)577 { 578 printf("\t%s\t : %s\n", c md[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); 579 580 } 580 581 } … … 624 625 unsigned int placement; // placement specified if non zero 625 626 unsigned int cxy; // target cluster if placement specified 627 628 #if DEBUG_CMD_LOAD 629 char string[64]; 630 #endif 626 631 627 632 if( (argc < 2) || (argc > 4) ) … … 661 666 } 662 667 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 */ 663 676 // get KSH process PID 664 677 ksh_pid = getpid(); 665 678 666 679 #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 ); 680 snprintf( string , 64 , "[KSH] %s : ksh_pid %x / path %s / bg %d / place %d (%x)\n", 681 __FUNCTION__, ksh_pid, argv[1], background, placement, cxy ); 682 display_string( string ); 671 683 #endif 672 684 … … 685 697 686 698 #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);699 snprintf( string , 64 , "[KSH] %s : child_pid %x after fork, before exec\n", 700 __FUNCTION__ , getpid() ); 701 display_string( string ); 690 702 #endif 691 703 … … 694 706 695 707 #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);708 snprintf( string , 64 , "[KSH] %s : child_pid %x after exec / ret_exec %x\n", 709 __FUNCTION__ , getpid(), ret_exec ); 710 display_string( string ); 699 711 #endif 700 712 … … 710 722 711 723 #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 ownership724 snprintf( string , 64 , "[KSH] %s : ksh_pid %x after fork / ret_fork %x\n", 725 __FUNCTION__, getpid(), ret_fork ); 726 display_string( string ); 727 #endif 728 729 if( background ) // KSH must keep TXT ownership 718 730 { 731 // get back the TXT ownership 719 732 fg( ksh_pid ); 733 734 // release semaphore to get next command 735 sem_post( &semaphore ); 720 736 } 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 } 727 744 } // end cmd_load 728 745 … … 758 775 DIR * dir; 759 776 777 #if DEBUG_CMD_LS 778 char string[64]; 779 #endif 780 760 781 if (argc > 2 ) 761 782 { … … 774 795 775 796 #if DEBUG_CMD_LS 776 printf("\n[ksh] %s : directory <%s> open / DIR %x\n",797 snprintf( string , 64 , "[KSH] %s : directory <%s> open / DIR %x\n", 777 798 __FUNCTION__, pathname , dir ); 799 display_string( string ); 778 800 #endif 779 801 … … 794 816 795 817 #if DEBUG_CMD_LS 796 printf("\n[ksh] %s : directory <%s> closed\n",818 snprintf( string , 64 , "[KSH] %s : directory <%s> closed\n", 797 819 __FUNCTION__, pathname ); 820 display_string( string ); 798 821 #endif 799 822 … … 865 888 unsigned int y; 866 889 890 #if DEBUG_CMD_PS 891 char string[64]; 892 #endif 893 867 894 if (argc != 1) 868 895 { … … 879 906 for( y = 0 ; y < y_size ; y++ ) 880 907 { 908 909 #if DEBUG_CMD_PS 910 snprintf( string , 64 , "\n[KSH] %s : call display_cluster_process()", __FUNCTION__ ); 911 display_string( string ); 912 #endif 913 881 914 // display only owned processes 882 915 display_cluster_processes( HAL_CXY_FROM_XY(x,y), 1 ); … … 1003 1036 /////////////////////////////////////////////////////////////////////////////////// 1004 1037 1005 ksh_cmd_t c md[] =1038 ksh_cmd_t command[] = 1006 1039 { 1007 1040 { "cat", "display file content", cmd_cat }, … … 1031 1064 static void __attribute__ ((noinline)) parse( char * buf ) 1032 1065 { 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 1072 char string[64]; 1073 snprintf( string , 64 , "\n[KSH] %s : <%s>", __FUNCTION__ , buf ); 1074 display_string( string ); 1075 #endif 1037 1076 1038 1077 // build argc/argv 1039 1078 for (i = 0; i < len; i++) 1040 1079 { 1080 // convert SPACE to NUL 1041 1081 if (buf[i] == ' ') 1042 1082 { … … 1053 1093 } 1054 1094 1095 #if DEBUG_PARSE 1096 snprintf( string , 64 , "\n[KSH] %s : argc = %d for <%s>", __FUNCTION__ , argc , argv[0] ); 1097 display_string( string ); 1098 #endif 1099 1055 1100 // analyse command type 1056 1101 if (argc > 0) … … 1058 1103 int found = 0; 1059 1104 1060 argv[argc] = NULL;1061 1062 1105 // try to match typed command 1063 for ( i = 0 ; cmd[i].name ; i++)1064 { 1065 if (strcmp(argv[0], c md[i].name) == 0)1106 for ( i = 0 ; command[i].name ; i++ ) 1107 { 1108 if (strcmp(argv[0], command[i].name) == 0) 1066 1109 { 1067 c md[i].fn(argc, argv);1110 command[i].fn(argc, argv); 1068 1111 found = 1; 1069 1112 break; … … 1085 1128 { 1086 1129 char c; // read character 1087 char buf[CMD_MAX_SIZE]; // buffer for one command1088 1130 unsigned int end_command; // last character found in a command 1089 1131 unsigned int count; // pointer in command buffer … … 1091 1133 unsigned int state; // escape sequence state 1092 1134 1135 char cmd[CMD_MAX_SIZE]; // buffer for one command 1136 1137 #if DEBUG_INTER 1138 char string[64]; 1139 #endif 1093 1140 1094 1141 /* To lauch one command without interactive mode 1095 1096 1142 if( sem_wait( &semaphore ) ) 1097 1143 { … … 1101 1147 else 1102 1148 { 1103 printf("\n[ksh] l s bin/user\n");1149 printf("\n[ksh] load bin/user/sort.elf\n"); 1104 1150 } 1105 1151 1106 strcpy( buf , "ls bin/user" ); 1107 parse( buf ); 1108 1152 strcpy( cmd , "load bin/user/sort.elf" ); 1153 parse( cmd ); 1109 1154 */ 1110 1155 … … 1127 1172 // - BRAKET : the wo characters (ESC,[) have been found 1128 1173 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 1131 1185 while (1) 1132 1186 { 1133 1187 // 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; 1148 1191 end_command = 0; 1192 1193 #if DEBUG_INTER 1194 unsigned int pid = getpid(); 1195 snprintf( string , 64 , "\n[KSH] %s : request a new command", __FUNCTION__ ); 1196 display_string( string ); 1197 #endif 1149 1198 1150 1199 // internal loop on characters in one command … … 1171 1220 { 1172 1221 // complete command with NUL character 1173 buf[count] = 0;1222 cmd[count] = 0; 1174 1223 count++; 1175 1224 1176 // register command in log arrays 1177 str cpy(log_entries[ptw].buf, buf);1225 // register command in log 1226 strncpy( log_entries[ptw].buf , cmd , count ); 1178 1227 log_entries[ptw].count = count; 1179 1228 ptw = (ptw + 1) % LOG_DEPTH; 1180 1229 ptr = ptw; 1181 1230 1231 #if DEBUG_INTER 1232 snprintf( string , 64 , "[KSH] %s : parse and execute <%s>", __FUNCTION__, cmd ); 1233 display_string( string ); 1234 #endif 1182 1235 // echo character 1183 1236 putchar( c ); 1184 1237 1185 1238 // call parser to analyse and execute command 1186 parse( buf);1239 parse( cmd ); 1187 1240 } 1188 1241 else // no command registered … … 1204 1257 else // normal character 1205 1258 { 1206 if (count < sizeof(buf) - 1)1259 if (count < (sizeof(cmd) - 1) ) 1207 1260 { 1208 1261 // register character in command buffer 1209 buf[count] = c;1262 cmd[count] = c; 1210 1263 count++; 1211 1264 … … 1213 1266 putchar( c ); 1214 1267 } 1268 else 1269 { 1270 printf("\none command cannot exceed %d characters\n", sizeof(cmd) ); 1271 } 1215 1272 } 1216 1273 } … … 1228 1285 else if( state == BRAKET ) 1229 1286 { 1230 if (c == 'D') // valid LEFT sequence => move bufpointer left1287 if (c == 'D') // valid LEFT sequence => move cmd pointer left 1231 1288 { 1232 1289 if (count > 0) … … 1239 1296 state = NORMAL; 1240 1297 } 1241 else if (c == 'C') // valid RIGHT sequence => move bufpointer right1298 else if (c == 'C') // valid RIGHT sequence => move cmd pointer right 1242 1299 { 1243 if (count < sizeof( buf) - 1)1300 if (count < sizeof(cmd) - 1) 1244 1301 { 1245 printf("%c", buf[count]);1302 printf("%c", cmd[count]); 1246 1303 count++; 1247 1304 } … … 1256 1313 count = 0; 1257 1314 1258 // copy log command into buf1315 // copy log command into cmd 1259 1316 ptr = (ptr - 1) % LOG_DEPTH; 1260 strcpy( buf, log_entries[ptr].buf);1317 strcpy(cmd, log_entries[ptr].buf); 1261 1318 count = log_entries[ptr].count - 1; 1262 1319 1263 1320 // display log command 1264 printf("%s", buf);1321 printf("%s", cmd); 1265 1322 1266 1323 // get next user char … … 1273 1330 count = 0; 1274 1331 1275 // copy log command into buf1332 // copy log command into cmd 1276 1333 ptr = (ptr + 1) % LOG_DEPTH; 1277 strcpy( buf, log_entries[ptr].buf);1334 strcpy(cmd, log_entries[ptr].buf); 1278 1335 count = log_entries[ptr].count; 1279 1336 1280 1337 // display log command 1281 printf("%s", buf);1338 printf("%s", cmd); 1282 1339 1283 1340 // get next user char … … 1291 1348 } 1292 1349 } // end internal while loop on characters 1350 1351 #if DEBUG_INTER 1352 snprintf( string , 64 , "\n[KSH] %s : complete <%s> command", __FUNCTION__, cmd ); 1353 display_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 1293 1366 } // end external while loop on commands 1367 1294 1368 } // end interactive() 1295 1369 … … 1302 1376 int child_pid; // child process identifier 1303 1377 int parent_pid; // parent process identifier (i.e. this process) 1304 pthread_t trdid; // interactive thread identifier (unused)1305 1378 unsigned int is_owner; // non-zero if KSH process is TXT owner 1306 1379 … … 1315 1388 1316 1389 #if DEBUG_MAIN 1317 printf("\n[ksh] main started on core[%x,%d]\n", cxy , lid );1390 printf("\n[ksh] main thread started on core[%x,%d]\n", cxy , lid ); 1318 1391 #endif 1319 1392 … … 1339 1412 NULL ); 1340 1413 #if DEBUG_MAIN 1341 printf("\n[ksh] main launched interactive thread => wait children termination\n");1414 printf("\n[ksh] main thread launched interactive thread %x\n", trdid ); 1342 1415 #endif 1343 1416 … … 1360 1433 is_fg( parent_pid , &is_owner ); 1361 1434 if( is_owner ) sem_post( &semaphore ); 1362 1363 1435 } 1364 1436 } // end main()
Note: See TracChangeset
for help on using the changeset viewer.