Changeset 444 for trunk/libs/mini-libc/stdlib.c
- Timestamp:
- May 16, 2018, 8:31:35 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libs/mini-libc/stdlib.c
r443 r444 22 22 */ 23 23 24 #include <stdlib.h> 24 25 #include <stdio.h> 25 #include <stdarg.h> 26 #include <pthread.h> 27 #include <stdlib.h> 28 29 ///////////////////////////// 30 void assert( int expression ) 31 { 32 if( expression == 0 ) 33 { 34 printf("\n[ASSERT FAILED] in %s at line %d in file %s\n", 35 __FUNCTION__ , __LINE__ , __FILE__ ); 36 37 exit( 0 ); 38 } 39 } 40 26 #include <almos-mkh.h> 27 #include <hal_user.h> 28 #include <syscalls_numbers.h> 29 30 #define reg_t int 41 31 ////////////////////////// 42 32 int atoi(const char * str) … … 124 114 } 125 115 126 /////////////////////////////////////////////////////////////// 127 void * memcpy(void *_dst, const void * _src, unsigned int size) 128 { 129 unsigned int * dst = _dst; 130 const unsigned int * src = _src; 131 if (!((unsigned int) dst & 3) && !((unsigned int) src & 3) ) 132 { 133 while (size > 3) 134 { 135 *dst++ = *src++; 136 size -= 4; 137 } 138 } 139 140 unsigned char *cdst = (unsigned char*)dst; 141 unsigned char *csrc = (unsigned char*)src; 142 143 while (size--) 144 { 145 *cdst++ = *csrc++; 146 } 147 return _dst; 148 } 149 150 ////////////////////////////////////////////////////////// 151 inline void * memset(void * dst, int s, unsigned int size) 152 { 153 char * a = (char *) dst; 154 while (size--) 155 { 156 *a++ = (char)s; 157 } 158 return dst; 159 } 160 161 162 ////////////////////////////////////////// 163 static int xprintf( char * string, 164 unsigned int length, 165 const char * format, 166 va_list * args ) 167 { 168 unsigned int ps = 0; // write index to the string buffer 169 170 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0); 171 172 xprintf_text: 173 174 while ( *format != 0 ) 175 { 176 177 if (*format == '%') // copy argument to string 178 { 179 format++; 180 goto xprintf_arguments; 181 } 182 else // copy one char to string 183 { 184 TO_STREAM( *format ); 185 format++; 186 } 187 } 188 189 return ps; 190 191 xprintf_arguments: 192 193 { 194 char buf[30]; // buffer to display one number 195 char * pbuf; // pointer on first char to display 196 unsigned int len = 0; // number of char to display 197 static const char HexaTab[] = "0123456789ABCDEF"; 198 unsigned int i; 199 200 // Ignore fields width and precision 201 for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ ); 202 203 switch (*format) 204 { 205 case ('c'): // char conversion 206 { 207 int val = va_arg( *args, int ); 208 buf[0] = val; 209 pbuf = buf; 210 len = 1; 211 break; 212 } 213 case ('d'): // decimal signed integer 214 { 215 int val = va_arg( *args, int ); 216 if (val < 0) 217 { 218 TO_STREAM( '-' ); 219 val = -val; 220 } 221 for(i = 0; i < 10; i++) 222 { 223 224 buf[9 - i] = HexaTab[val % 10]; 225 if (!(val /= 10)) break; 226 } 227 len = i + 1; 228 pbuf = &buf[9 - i]; 229 break; 230 } 231 case ('u'): // decimal unsigned integer 232 { 233 unsigned int val = va_arg( *args, unsigned int ); 234 for(i = 0; i < 10; i++) 235 { 236 buf[9 - i] = HexaTab[val % 10]; 237 if (!(val /= 10)) break; 238 } 239 len = i + 1; 240 pbuf = &buf[9 - i]; 241 break; 242 } 243 case ('x'): // 32 bits hexadecimal 244 case ('l'): // 64 bits hexadecimal 245 { 246 unsigned int imax; 247 unsigned long long val; 248 249 if ( *format == 'l' ) // 64 bits 250 { 251 val = va_arg( *args, unsigned long long); 252 imax = 16; 253 } 254 else // 32 bits 255 { 256 val = va_arg( *args, unsigned int); 257 imax = 8; 258 } 259 260 TO_STREAM( '0' ); 261 TO_STREAM( 'x' ); 262 263 for(i = 0; i < imax; i++) 264 { 265 buf[(imax-1) - i] = HexaTab[val % 16]; 266 if (!(val /= 16)) break; 267 } 268 len = i + 1; 269 pbuf = &buf[(imax-1) - i]; 270 break; 271 } 272 case ('s'): /* string */ 273 { 274 char* str = va_arg( *args, char* ); 275 while (str[len]) { len++; } 276 pbuf = str; 277 break; 278 } 279 /* 280 case ('f'): // IEEE754 64 bits 281 // integer part : up to 10 decimal digits 282 // decimal part : 9 decimal digits 283 { 284 union 285 { 286 double d; 287 unsigned long long ull; 288 } val; 289 290 val.d = va_arg( *args, double ); 291 292 unsigned long long mantisse; 293 mantisse = val.ull & 0xFFFFFFFFFFFFFULL; // mantisse 294 295 unsigned int exp; 296 exp = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp 297 298 if (exp == 0x7FF) // special values 299 { 300 if (mantisse & 0xFFFFFFFFFFFFFULL) // Not a Number 301 { 302 buf[0] = 'N'; 303 buf[1] = 'a'; 304 buf[2] = 'N'; 305 len = 3; 306 pbuf = buf; 307 } 308 else // infinite 309 { 310 // inf 311 buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+'; 312 buf[1] = 'i'; 313 buf[2] = 'n'; 314 buf[3] = 'f'; 315 len = 4; 316 pbuf = buf; 317 } 318 break; 319 } 320 321 // display sign & analyse overflow 322 unsigned int overflow = 0; 323 if (val.ull & 0x8000000000000000ULL) // negative 324 { 325 TO_STREAM( '-' ); 326 val.d = val.d * -1; 327 if( val.d < -9999999999.0) overflow = 1; 328 } 329 else // positive 330 { 331 TO_STREAM( '+' ); 332 if( val.d > 9999999999.0) overflow = 1; 333 } 334 335 // check overflow caused by the 10.9 format 336 if ( overflow ) 337 { 338 buf[0] = 'o'; 339 buf[1] = 'v'; 340 buf[2] = 'r'; 341 len = 3; 342 pbuf = buf; 343 break; 344 } 345 346 // compute integer & decimal parts 347 unsigned int intp; // integer part 348 unsigned int decp; // decimal part 349 intp = (unsigned int)val.d; 350 val.d -= (double)intp; 351 decp = (unsigned int)(val.d * 1000000000); 352 353 // display decimal value in 10.9 format 354 for(i = 0; i < 10; i++) 355 { 356 buf[9 - i] = HexaTab[intp % 10]; 357 if (!(intp /= 10)) break; 358 } 359 pbuf = &buf[9 - i]; 360 len = i+11; 361 buf[10] = '.'; 362 for(i = 0; i < 9; i++) 363 { 364 buf[19 - i] = HexaTab[decp % 10]; 365 decp /= 10; 366 } 367 break; 368 } 369 */ 370 default: // unsupported argument type 371 { 372 return -1; 373 } 374 } // end switch on argument type 375 376 format++; 377 378 // copy argument to string 379 for( i = 0 ; i < len ; i++ ) 380 { 381 TO_STREAM( pbuf[i] ); 382 } 383 384 goto xprintf_text; 385 } 386 } // end xprintf() 387 388 ////////////////////////////////////// 389 int printf( const char * format, ... ) 390 { 391 char string[4096]; 392 va_list args; 393 int count; 394 395 va_start( args, format ); 396 count = xprintf( string , 4095 , format , &args ); 397 va_end( args ); 398 399 if ( count == -1 ) 400 { 401 display_string( "stdlib : xprintf failure" ); 402 return -1; 403 } 404 else 405 { 406 string[count] = 0; 407 return write( 1 , &string , count + 1 ); 408 } 409 } 410 411 ///////////// 412 int getchar() 413 { 414 char byte; 415 416 if ( read( 0 , &byte , 1 ) != 1 ) return 0; 417 else return (int)byte; 418 } 419 420 //////////////////// 421 int putchar( int c ) 422 { 423 char byte = (char)c; 424 425 if( write( 1 , &byte , 1 ) != 1 ) return 0; 426 else return c; 427 } 428 429 //////////// 430 int getint() 431 { 432 unsigned int i; 433 int val; // ASCII character value 434 435 unsigned char buf[32]; 436 unsigned int save = 0; 437 unsigned int dec = 0; 438 unsigned int done = 0; 439 unsigned int overflow = 0; 440 unsigned int length = 0; 441 442 // get characters 443 while (done == 0) 444 { 445 // read one character 446 val = getchar(); 447 448 // analyse character 449 if ((val > 0x2F) && (val < 0x3A)) // decimal character 450 { 451 buf[length] = (unsigned char)val; 452 length++; 453 putchar( val ); // echo 454 } 455 else if (val == 0x0A) // LF character 456 { 457 done = 1; 458 } 459 else if ( (val == 0x7F) || // DEL character 460 (val == 0x08) ) // BS character 461 { 462 if ( length > 0 ) 463 { 464 length--; 465 printf("\b \b"); // BS / / BS 466 } 467 } 468 else if ( val == 0 ) // EOF 469 { 470 return -1; 471 } 472 473 // test buffer overflow 474 if ( length >= 32 ) 475 { 476 overflow = 1; 477 done = 1; 478 } 479 } // end while characters 480 481 // string to int conversion with overflow detection 482 if ( overflow == 0 ) 483 { 484 for (i = 0; (i < length) && (overflow == 0) ; i++) 485 { 486 dec = dec * 10 + (buf[i] - 0x30); 487 if (dec < save) overflow = 1; 488 save = dec; 489 } 490 } 491 492 // final evaluation 493 if ( overflow == 0 ) 494 { 495 // return value 496 return dec; 497 } 498 else 499 { 500 // cancel all echo characters 501 for (i = 0; i < length ; i++) 502 { 503 printf("\b \b"); // BS / / BS 504 } 505 506 // echo character '0' 507 putchar( '0' ); 508 509 // return 0 value 510 return 0; 511 } 512 } // end getint() 513 514 /////////////////////////////////////// 515 int snprintf( char * string, 516 unsigned int length, 517 const char * format, ... ) 518 { 519 va_list args; 520 int count; 521 522 va_start( args, format ); 523 count = xprintf( string , length , format , &args ); 524 va_end( args ); 525 526 if( count < length ) string[count] = 0; 527 528 return count; 529 } 116 530 117 531 118 ////////// … … 554 141 } 555 142 556 /////////// 557 void idbg() 558 { 559 char cmd; 560 unsigned int cxy; 561 unsigned int lid; 562 unsigned int txt; 563 unsigned int active; 564 565 while( 1 ) 566 { 567 printf("\n[idbg] cmd = "); 568 cmd = (char)getchar(); 569 570 if( cmd == 'h' ) 571 { 572 printf("h\n" 573 "p : display on TXT0 process descriptors in cluster[cxy]\n" 574 "s : display on TXT0 scheduler state for core[cxy,lid]\n" 575 "v : display on TXT0 VMM for calling process in cluster [cxy]\n" 576 "t : display on TXT0 process decriptors attached to TXT[tid]\n" 577 "y : activate/desactivate trace for core[cxy,lid]\n" 578 "x : force calling process to exit\n" 579 "c : resume calling process execution\n" 580 "h : list supported commands\n"); 581 } 582 else if( cmd == 'p' ) 583 { 584 printf("p / cxy = "); 585 cxy = getint(); 586 display_cluster_processes( cxy ); 587 } 588 else if( cmd == 's' ) 589 { 590 printf("s / cxy = "); 591 cxy = getint(); 592 printf(" / lid = "); 593 lid = getint(); 594 display_sched( cxy , lid ); 595 } 596 else if( cmd == 'v' ) 597 { 598 printf("v / cxy = "); 599 cxy = getint(); 600 display_vmm( cxy , (unsigned int)getpid() ); 601 } 602 else if( cmd == 't' ) 603 { 604 printf("t / txt_id = "); 605 txt = getint(); 606 display_txt_processes( txt ); 607 } 608 else if( cmd == 'y' ) 609 { 610 printf("y / active = "); 611 active = getint(); 612 printf(" / cxy = "); 613 cxy = getint(); 614 printf(" / lid = "); 615 lid = getint(); 616 trace( active , cxy , lid ); 617 } 618 else if( cmd == 'x' ) 619 { 620 printf("x\n"); 621 exit( 0 ); 622 } 623 else if( cmd == 'c' ) 624 { 625 printf("c\n"); 626 break; 627 } 628 } 629 } // end idbg() 630 631 632 143 144 145 146 ////////////////////////////////// 147 void * malloc( unsigned int size ) 148 { 149 // get cluster identifier 150 unsigned int cxy; 151 unsigned int lid; 152 get_core( &cxy , &lid ); 153 154 return remote_malloc( size, cxy ); 155 } 156 157 158 159 /////////////////////////////////// 160 void * calloc ( unsigned int count, 161 unsigned int size ) 162 { 163 // get calling core cluster identifier 164 unsigned int cxy; 165 unsigned int lid; 166 get_core( &cxy , &lid ); 167 168 return remote_calloc( count , size , cxy ); 169 } 170 171 /////////////////////////////////// 172 void * realloc ( void * ptr, 173 unsigned int size ) 174 { 175 // get calling core cluster identifier 176 unsigned int cxy; 177 unsigned int lid; 178 get_core( &cxy , &lid ); 179 180 return remote_realloc( ptr , size , cxy ); 181 } 182 183 /////////////////////// 184 void free( void * ptr ) 185 { 186 // get calling core cluster identifier 187 unsigned int cxy; 188 unsigned int lid; 189 get_core( &cxy , &lid ); 190 191 remote_free( ptr , cxy ); 192 } 193 194 /////////////////////// 195 void exit( int status ) 196 { 197 hal_user_syscall( SYS_EXIT, 198 (reg_t)status, 0, 0, 0 ); 199 } 200 201
Note: See TracChangeset
for help on using the changeset viewer.