Changeset 444 for trunk/libs/mini-libc
- Timestamp:
- May 16, 2018, 8:31:35 PM (6 years ago)
- Location:
- trunk/libs/mini-libc
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libs/mini-libc/Makefile
r440 r444 8 8 endif 9 9 10 SRCS = malloc.c stdio.c stdlib.c string.c 11 10 SRCS = ctype.c dirent.c fcntl.c signal.c stdio.c stdlib.c string.c strings.c sys/mman.c sys/stat.c sys/time.c sys/wait.c unistd.c 12 11 OBJS = $(addprefix build/, $(SRCS:.c=.o)) \ 13 12 $(HAL_ARCH)/build/core/hal_user.o 14 13 15 INCLUDES = -I. -I$( KERNEL)/syscalls -I$(HAL)/generic -I../mini-libpthread14 INCLUDES = -I. -I$(HAL)/generic -I$(LIBPTHREAD_INCLUDE) -I$(LIBALMOSMKH_INCLUDE) -I$(SHARED_INCLUDE) 16 15 17 libs : build/lib/libc.a 16 libs : build/lib/libc.a headers 18 17 19 18 build : 20 19 @mkdir build 20 @mkdir build/sys 21 21 @mkdir build/lib 22 22 @mkdir build/include 23 @mkdir build/include/sys 23 24 24 25 $(HAL_ARCH)/build/core/hal_user.o : … … 30 31 $(DU) -D $@ > $@.txt 31 32 33 headers: build 34 cp $(SRCS:.c=.h) assert.h build/include/. 35 cp sys/*.h build/include/sys/. 36 32 37 build/lib/libc.a: build $(OBJS) 33 38 $(AR) rc $@ $(OBJS) 39 ranlib $@ 34 40 $(RANLIB) $@ 35 cp $(SRCS:.c=.h) $(HAL)/generic/hal_user.h $(KERNEL)/syscalls/shared_syscalls.h build/include/.36 41 37 .PHONY = build clean 42 .PHONY = build clean headers 38 43 39 44 40 45 clean: 41 rm - f build/*.o build/*.txt build/include/* build/lib/*46 rm -rf build/ -
trunk/libs/mini-libc/stdio.c
r443 r444 22 22 */ 23 23 24 #include <shared_syscalls.h>25 #include <hal_user.h>26 24 #include <stdio.h> 27 #include <stdlib.h> 28 29 #define reg_t int 30 31 ///////////// POSIX standard system calls //////////////////////////////////// 32 33 /////////////////////// 34 void exit( int status ) 35 { 36 hal_user_syscall( SYS_EXIT, 37 (reg_t)status, 0, 0, 0 ); 25 #include <stdarg.h> 26 #include <unistd.h> 27 #include <almos-mkh.h> 28 ////////////////////////////////////////// 29 static int xprintf( char * string, 30 unsigned int length, 31 const char * format, 32 va_list * args ) 33 { 34 unsigned int ps = 0; // write index to the string buffer 35 36 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0); 37 38 xprintf_text: 39 40 while ( *format != 0 ) 41 { 42 43 if (*format == '%') // copy argument to string 44 { 45 format++; 46 goto xprintf_arguments; 47 } 48 else // copy one char to string 49 { 50 TO_STREAM( *format ); 51 format++; 52 } 53 } 54 55 return ps; 56 57 xprintf_arguments: 58 59 { 60 char buf[30]; // buffer to display one number 61 char * pbuf; // pointer on first char to display 62 unsigned int len = 0; // number of char to display 63 static const char HexaTab[] = "0123456789ABCDEF"; 64 unsigned int i; 65 66 // Ignore fields width and precision 67 for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ ); 68 69 switch (*format) 70 { 71 case ('c'): // char conversion 72 { 73 int val = va_arg( *args, int ); 74 buf[0] = val; 75 pbuf = buf; 76 len = 1; 77 break; 78 } 79 case ('d'): // decimal signed integer 80 { 81 int val = va_arg( *args, int ); 82 if (val < 0) 83 { 84 TO_STREAM( '-' ); 85 val = -val; 86 } 87 for(i = 0; i < 10; i++) 88 { 89 90 buf[9 - i] = HexaTab[val % 10]; 91 if (!(val /= 10)) break; 92 } 93 len = i + 1; 94 pbuf = &buf[9 - i]; 95 break; 96 } 97 case ('u'): // decimal unsigned integer 98 { 99 unsigned int val = va_arg( *args, unsigned int ); 100 for(i = 0; i < 10; i++) 101 { 102 buf[9 - i] = HexaTab[val % 10]; 103 if (!(val /= 10)) break; 104 } 105 len = i + 1; 106 pbuf = &buf[9 - i]; 107 break; 108 } 109 case ('x'): // 32 bits hexadecimal 110 case ('l'): // 64 bits hexadecimal 111 { 112 unsigned int imax; 113 unsigned long long val; 114 115 if ( *format == 'l' ) // 64 bits 116 { 117 val = va_arg( *args, unsigned long long); 118 imax = 16; 119 } 120 else // 32 bits 121 { 122 val = va_arg( *args, unsigned int); 123 imax = 8; 124 } 125 126 TO_STREAM( '0' ); 127 TO_STREAM( 'x' ); 128 129 for(i = 0; i < imax; i++) 130 { 131 buf[(imax-1) - i] = HexaTab[val % 16]; 132 if (!(val /= 16)) break; 133 } 134 len = i + 1; 135 pbuf = &buf[(imax-1) - i]; 136 break; 137 } 138 case ('s'): /* string */ 139 { 140 char* str = va_arg( *args, char* ); 141 while (str[len]) { len++; } 142 pbuf = str; 143 break; 144 } 145 /* 146 case ('f'): // IEEE754 64 bits 147 // integer part : up to 10 decimal digits 148 // decimal part : 9 decimal digits 149 { 150 union 151 { 152 double d; 153 unsigned long long ull; 154 } val; 155 156 val.d = va_arg( *args, double ); 157 158 unsigned long long mantisse; 159 mantisse = val.ull & 0xFFFFFFFFFFFFFULL; // mantisse 160 161 unsigned int exp; 162 exp = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp 163 164 if (exp == 0x7FF) // special values 165 { 166 if (mantisse & 0xFFFFFFFFFFFFFULL) // Not a Number 167 { 168 buf[0] = 'N'; 169 buf[1] = 'a'; 170 buf[2] = 'N'; 171 len = 3; 172 pbuf = buf; 173 } 174 else // infinite 175 { 176 // inf 177 buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+'; 178 buf[1] = 'i'; 179 buf[2] = 'n'; 180 buf[3] = 'f'; 181 len = 4; 182 pbuf = buf; 183 } 184 break; 185 } 186 187 // display sign & analyse overflow 188 unsigned int overflow = 0; 189 if (val.ull & 0x8000000000000000ULL) // negative 190 { 191 TO_STREAM( '-' ); 192 val.d = val.d * -1; 193 if( val.d < -9999999999.0) overflow = 1; 194 } 195 else // positive 196 { 197 TO_STREAM( '+' ); 198 if( val.d > 9999999999.0) overflow = 1; 199 } 200 201 // check overflow caused by the 10.9 format 202 if ( overflow ) 203 { 204 buf[0] = 'o'; 205 buf[1] = 'v'; 206 buf[2] = 'r'; 207 len = 3; 208 pbuf = buf; 209 break; 210 } 211 212 // compute integer & decimal parts 213 unsigned int intp; // integer part 214 unsigned int decp; // decimal part 215 intp = (unsigned int)val.d; 216 val.d -= (double)intp; 217 decp = (unsigned int)(val.d * 1000000000); 218 219 // display decimal value in 10.9 format 220 for(i = 0; i < 10; i++) 221 { 222 buf[9 - i] = HexaTab[intp % 10]; 223 if (!(intp /= 10)) break; 224 } 225 pbuf = &buf[9 - i]; 226 len = i+11; 227 buf[10] = '.'; 228 for(i = 0; i < 9; i++) 229 { 230 buf[19 - i] = HexaTab[decp % 10]; 231 decp /= 10; 232 } 233 break; 234 } 235 */ 236 default: // unsupported argument type 237 { 238 return -1; 239 } 240 } // end switch on argument type 241 242 format++; 243 244 // copy argument to string 245 for( i = 0 ; i < len ; i++ ) 246 { 247 TO_STREAM( pbuf[i] ); 248 } 249 250 goto xprintf_text; 251 } 252 } // end xprintf() 253 254 ////////////////////////////////////// 255 int printf( const char * format, ... ) 256 { 257 char string[4096]; 258 va_list args; 259 int count; 260 261 va_start( args, format ); 262 count = xprintf( string , 4095 , format , &args ); 263 va_end( args ); 264 265 if ( count == -1 ) 266 { 267 display_string( "stdlib : xprintf failure" ); 268 return -1; 269 } 270 else 271 { 272 string[count] = 0; 273 return write( 1 , &string , count + 1 ); 274 } 38 275 } 39 276 40 ///////////// ////////////////////41 int munmap( void * addr,42 unsigned int size ) 43 { 44 return hal_user_syscall( SYS_MUNMAP, 45 (reg_t)addr,46 (reg_t)size, 0, 0 );277 ///////////// 278 int getchar() 279 { 280 char byte; 281 282 if ( read( 0 , &byte , 1 ) != 1 ) return 0; 283 else return (int)byte; 47 284 } 48 285 49 //////////////////////////////// 50 int open( const char * pathname, 51 int flags, 52 int mode ) 53 { 54 return hal_user_syscall( SYS_OPEN, 55 (reg_t)pathname, 56 (reg_t)flags, 57 (reg_t)mode, 0 ); 286 //////////////////// 287 int putchar( int c ) 288 { 289 char byte = (char)c; 290 291 if( write( 1 , &byte , 1 ) != 1 ) return 0; 292 else return c; 58 293 } 59 294 60 /////////////////////////////// 61 void * mmap( void * addr, 62 unsigned int length, 63 int prot, 64 int flags, 65 int fd, 66 unsigned int offset ) 67 { 68 mmap_attr_t attr; 69 attr.addr = addr; 70 attr.length = length; 71 attr.prot = prot; 72 attr.flags = flags; 73 attr.fdid = fd; 74 attr.offset = offset; 75 76 if( hal_user_syscall( SYS_MMAP, 77 (reg_t)&attr, 0, 0, 0 ) ) return NULL; 78 else return attr.addr; 295 /////////////////////////////////////// 296 int snprintf( char * string, 297 unsigned int length, 298 const char * format, ... ) 299 { 300 va_list args; 301 int count; 302 303 va_start( args, format ); 304 count = xprintf( string , length , format , &args ); 305 va_end( args ); 306 307 if( count < length ) string[count] = 0; 308 309 return count; 79 310 } 80 311 81 ////////////////////////// 82 int read( int fd, 83 void * buf, 84 unsigned int count ) 85 { 86 return hal_user_syscall( SYS_READ, 87 (reg_t)fd, 88 (reg_t)buf, 89 (reg_t)count, 0 ); 90 } 91 92 /////////////////////////// 93 int write( int fd, 94 const void * buf, 95 unsigned int count ) 96 { 97 return hal_user_syscall( SYS_WRITE, 98 (reg_t)fd, 99 (reg_t)buf, 100 (reg_t)count, 0 ); 101 } 102 103 /////////////////////////// 104 int lseek( int fd, 105 unsigned int offset, 106 int whence ) 107 { 108 return hal_user_syscall( SYS_LSEEK, 109 (reg_t)fd, 110 (reg_t)offset, 111 (reg_t)whence, 0 ); 112 } 113 114 /////////////////// 115 int close( int fd ) 116 { 117 return hal_user_syscall( SYS_CLOSE, 118 (reg_t)fd, 0, 0, 0 ); 119 } 120 121 /////////////////////////////////// 122 int unlink( const char * pathname ) 123 { 124 return hal_user_syscall( SYS_UNLINK, 125 (reg_t)pathname, 0, 0, 0 ); 126 } 127 128 ///////////////////// 129 int pipe( int fd[2] ) 130 { 131 return -1; 132 } 133 134 ////////////////////////////////// 135 int chdir( const char * pathname ) 136 { 137 return hal_user_syscall( SYS_CHDIR, 138 (reg_t)pathname, 0, 0, 0 ); 139 } 140 141 ///////////////////////////////// 142 int mkdir( const char * pathname, 143 int mode ) 144 { 145 return hal_user_syscall( SYS_MKDIR, 146 (reg_t)pathname, 147 (reg_t)mode, 0, 0 ); 148 } 149 150 ////////////////////////////////// 151 int mkfifo( const char * pathname, 152 int mode ) 153 { 154 return hal_user_syscall( SYS_MKFIFO, 155 (reg_t)pathname, 156 (reg_t)mode, 0, 0 ); 157 } 158 159 ////////////////////////////////////// 160 DIR * opendir( const char * pathname ) 161 { 162 DIR * dirp; 163 int error; 164 error = hal_user_syscall( SYS_OPENDIR, 165 (reg_t)pathname, 166 (reg_t)&dirp, 0, 0 ); 167 if( error ) return NULL; 168 else return dirp; 169 } 170 171 ///////////////////////////////////// 172 struct dirent * readdir( DIR * dirp ) 173 { 174 struct dirent * dentp; 175 int error; 176 error = hal_user_syscall( SYS_READDIR, 177 (reg_t)dirp, 178 (reg_t)&dentp, 0, 0 ); 179 if( error ) return NULL; 180 else return dentp; 181 } 182 183 ////////////////////////// 184 int closedir( DIR * dirp ) 185 { 186 return hal_user_syscall( SYS_CLOSEDIR, 187 (reg_t)dirp, 0, 0, 0 ); 188 } 189 190 ///////////////////////////// 191 int getcwd( char * buf, 192 unsigned int bytes ) 193 { 194 return hal_user_syscall( SYS_GETCWD, 195 (reg_t)buf, 196 (reg_t)bytes, 0, 0 ); 197 } 198 199 //////////////////////////// 200 int rmdir( char * pathname ) 201 { 202 return hal_user_syscall( SYS_RMDIR, 203 (reg_t)pathname, 0, 0, 0 ); 204 } 205 206 ///////////////////////////////// 207 int utls( unsigned int operation, 208 unsigned int value ) 209 { 210 return hal_user_syscall( SYS_UTLS, 211 (reg_t)operation, 212 (reg_t)value, 0, 0 ); 213 } 214 215 /////////////////////////////// 216 int chmod( char * pathname, 217 unsigned int rights ) 218 { 219 return hal_user_syscall( SYS_CHMOD, 220 (reg_t)pathname, 221 (reg_t)rights, 0, 0 ); 222 } 223 224 ///////////////////////////////// 225 int signal( unsigned int sigid, 226 void * handler ) 227 { 228 return hal_user_syscall( SYS_SIGNAL, 229 (reg_t)sigid, 230 (reg_t)handler, 0, 0 ); 231 } 232 233 /////////////////////////////////////// 234 int gettimeofday( struct timeval * tv, 235 struct timezone * tz ) 236 { 237 return hal_user_syscall( SYS_SIGNAL, 238 (reg_t)tv, 239 (reg_t)tz, 0, 0 ); 240 } 241 242 /////////////////////////// 243 int kill( unsigned int pid, 244 unsigned int sig_id ) 245 { 246 return hal_user_syscall( SYS_KILL, 247 (reg_t)pid, 248 (reg_t)sig_id, 0, 0 ); 249 } 250 251 //////////// 252 int getpid() 253 { 254 return hal_user_syscall( SYS_GETPID, 0, 0, 0, 0 ); 255 } 256 257 ////////// 258 int fork() 259 { 260 return hal_user_syscall( SYS_FORK, 0, 0, 0, 0 ); 261 } 262 263 /////////////////////////// 264 int exec( char * pathname, 265 char ** argv, 266 char ** envp ) 267 { 268 return hal_user_syscall( SYS_EXEC, 269 (reg_t)pathname, 270 (reg_t)argv, 271 (reg_t)envp, 0 ); 272 } 273 274 ///////////////////////////////// 275 int stat( const char * pathname, 276 struct stat * stat ) 277 { 278 return hal_user_syscall( SYS_STAT, 279 (reg_t)pathname, 280 (reg_t)stat, 0, 0 ); 281 } 282 283 //////////////////////// 284 int wait( int * status ) 285 { 286 return hal_user_syscall( SYS_WAIT, 287 (reg_t)status, 0, 0, 0 ); 288 } 289 290 291 292 ///////////// Non standard system calls //////////////////////////////////// 293 294 295 ////////////////////////// 296 int fg( unsigned int pid ) 297 { 298 return hal_user_syscall( SYS_FG, 299 (reg_t)pid, 0, 0, 0 ); 300 } 301 302 ////////////////////////////////////// 303 int get_config( unsigned int * x_size, 304 unsigned int * y_size, 305 unsigned int * ncores ) 306 { 307 return hal_user_syscall( SYS_GET_CONFIG, 308 (reg_t)x_size, 309 (reg_t)y_size, 310 (reg_t)ncores, 0 ); 311 } 312 313 ///////////////////////////////// 314 int get_core( unsigned int * cxy, 315 unsigned int * lid ) 316 { 317 return hal_user_syscall( SYS_GET_CORE, 318 (reg_t)cxy, 319 (reg_t)lid, 0, 0 ); 320 } 321 322 //////////////////////////////////// 323 void display_string( char * string ) 324 { 325 hal_user_syscall( SYS_DISPLAY, 326 DISPLAY_STRING, 327 (reg_t)string, 0, 0 ); 328 } 329 330 ////////////////////////////////// 331 int display_vmm( unsigned int cxy, 332 unsigned int pid ) 333 { 334 return hal_user_syscall( SYS_DISPLAY, 335 DISPLAY_VMM, 336 (reg_t)cxy, 337 (reg_t)pid, 0 ); 338 } 339 340 //////////////////////////////////// 341 int display_sched( unsigned int cxy, 342 unsigned int lid ) 343 { 344 return hal_user_syscall( SYS_DISPLAY, 345 DISPLAY_SCHED, 346 (reg_t)cxy, 347 (reg_t)lid, 0 ); 348 } 349 350 ///////////////////////////////////////////////// 351 int display_cluster_processes( unsigned int cxy ) 352 { 353 return hal_user_syscall( SYS_DISPLAY, 354 DISPLAY_CLUSTER_PROCESSES, 355 (reg_t)cxy, 0, 0 ); 356 } 357 358 /////////////////// 359 int display_chdev() 360 { 361 return hal_user_syscall( SYS_DISPLAY, 362 DISPLAY_CHDEV, 0, 0, 0 ); 363 } 364 365 ///////////////// 366 int display_vfs() 367 { 368 return hal_user_syscall( SYS_DISPLAY, 369 DISPLAY_VFS, 0, 0, 0 ); 370 } 371 372 //////////////////////////////////////////////// 373 int display_txt_processes( unsigned int txt_id ) 374 { 375 return hal_user_syscall( SYS_DISPLAY, 376 DISPLAY_TXT_PROCESSES, 377 (reg_t)txt_id, 0, 0 ); 378 } 379 380 /////////////////////////////////////////// 381 int get_cycle( unsigned long long * cycle ) 382 { 383 return hal_user_syscall( SYS_GET_CYCLE, 384 (reg_t)cycle, 0, 0, 0 ); 385 } 386 387 /////////////////////////////// 388 int trace( unsigned int active, 389 unsigned int cxy, 390 unsigned int lid ) 391 { 392 return hal_user_syscall( SYS_TRACE, 393 (reg_t)active, 394 (reg_t)cxy, 395 (reg_t)lid, 0 ); 396 } 397 398 312 313 314 315 -
trunk/libs/mini-libc/stdio.h
r443 r444 25 25 #define _STDIO_H_ 26 26 27 #include < shared_syscalls.h>27 #include <almos-mkh/stdio.h> 28 28 29 29 #define NULL (void *)0 30 /********************************************************************************************* 31 * This function writes a formated string to the standard "stdout" stream. 32 ********************************************************************************************* 33 * @ returns number of characters written if success / returns -1 if failure. 34 ********************************************************************************************/ 35 int printf( const char * format, ... ); 30 36 31 /****************** Standard (POSIX) system calls **************************************/ 37 /********************************************************************************************* 38 * This function writes one single character to the standard "stdout" stream. 39 ********************************************************************************************* 40 * @ returns written character code if success / returns 0 (EOF) if failure. 41 ********************************************************************************************/ 42 int putchar( int c ); 32 43 33 /***************************************************************************************** 34 * This function terminates a process.35 ***************************************************************************************** 36 * @ status : terminaison status : 0 / EXIT_SUCCESS / EXIT_FAILURE.37 **************************************************************************************** /38 void exit( int status);44 /********************************************************************************************* 45 * This function returns one single character from the standard "stdin" stream. 46 ********************************************************************************************* 47 * @ returns read character code if success / returns 0 (EOF) if failure. 48 ********************************************************************************************/ 49 int getchar(); 39 50 40 /***************************************************************************************** 41 * This function open or create an open file descriptor. 42 ***************************************************************************************** 43 * @ pathname : pathname (can be relative or absolute). 44 * @ flags : bit vector attributes (see syscalls). 45 * @ mode : access rights (if O_CREAT is set). 46 * @ return file descriptor index in fd_array if success / return -1 if failure. 47 ****************************************************************************************/ 48 int open( const char * pathname, 49 int flags, 50 int mode ); 51 52 /***************************************************************************************** 53 * This function map physical memory (or a file) in the calling thread virtual space. 54 ***************************************************************************************** 55 * @ addr : unused and unsupported : must be NULL. 56 * @ length : requested number of bytes. 57 * @ prot : RWX access modes. 58 * @ flags : MAP_FILE / MAP_ANON / MAP_PRIVATE / MAP_SHARED (defined in syscalls.h) 59 * @ fdid : file descriptor index (if MAP_FILE). 60 * @ offset : offset in file (if MAP_FILE) 61 * @ return 0 if success / return -1 if failure. 62 ****************************************************************************************/ 63 void * mmap( void * addr, 64 unsigned int length, 65 int prot, 66 int flags, 67 int fd, 68 unsigned int offset ); 69 70 /***************************************************************************************** 71 * This function read bytes from an open file identified by its file descriptor. 72 * This file can be a regular file or a character oriented device. 73 ***************************************************************************************** 74 * @ file_id : open file index in fd_array. 75 * @ buf : buffer virtual address in user space. 76 * @ count : number of bytes. 77 * @ return number of bytes actually read if success / returns -1 if failure. 78 ****************************************************************************************/ 79 int read( int fd, 80 void * buf, 81 unsigned int count ); 82 83 /***************************************************************************************** 84 * This function writes bytes to an open file identified by its file descriptor. 85 * This file can be a regular file or character oriented device. 86 ***************************************************************************************** 87 * @ file_id : open file index in fd_array. 88 * @ buf : buffer virtual address in user space. 89 * @ count : number of bytes. 90 * @ return number of bytes actually written if success / returns -1 if failure. 91 ****************************************************************************************/ 92 int write( int fd, 93 const void * buf, 94 unsigned int count ); 95 96 /***************************************************************************************** 97 * This function repositions the offset of the file descriptor identified by <file_id>, 98 * according to the operation type defined by the <whence> argument. 99 ***************************************************************************************** 100 * @ fd : open file index in fd_array. 101 * @ offset : used to compute new offset value. 102 * @ whence : operation type (SEEK_SET / SEEK_CUR / SEEK_END defined in syscalls.h) 103 * @ return 0 if success / returns -1 if failure. 104 ****************************************************************************************/ 105 int lseek( int fd, 106 unsigned int offset, 107 int whence ); 108 109 /***************************************************************************************** 110 * This function release the memory allocated for the file descriptor identified by 111 * the <file_id> argument, and remove the fd array_entry in all copies of the process 112 * descriptor. 113 ***************************************************************************************** 114 * fd : file descriptor index in fd_array. 115 * @ return 0 if success / returns -1 if failure. 116 ****************************************************************************************/ 117 int close( int fd ); 118 119 /***************************************************************************************** 120 * This function removes a directory entry identified by the <pathname> from the 121 * directory, and decrement the link count of the file referenced by the link. 122 * If the link count reduces to zero, and no process has the file open, then all resources 123 * associated with the file are released. If one or more process have the file open when 124 * the last link is removed, the link is removed, but the removal of the file is delayed 125 * until all references to it have been closed. 126 ***************************************************************************************** 127 * @ pathname : pathname (can be relative or absolute). 128 * @ return 0 if success / returns -1 if failure. 129 ****************************************************************************************/ 130 int unlink( const char * pathname ); 131 132 /***************************************************************************************** 133 * This function creates in the calling thread cluster an unnamed pipe, and two 134 * (read and write) file descriptors to access this pipe. The calling function must pass 135 * the pointer on the fd[] array. 136 * TODO not implemented yet... 137 ***************************************************************************************** 138 * @ file_id[0] : [out] read only file descriptor index. 139 * @ file_id[1] : [out] write only file descriptor index. 140 * @ return 0 if success / return -1 if failure. 141 ****************************************************************************************/ 142 int pipe( int fd[2] ); 143 144 /***************************************************************************************** 145 * This function change the current working directory in reference process descriptor. 146 ***************************************************************************************** 147 * @ pathname : pathname (can be relative or absolute). 148 * @ return 0 if success / returns -1 if failure. 149 ****************************************************************************************/ 150 int chdir( const char * pathname ); 151 152 /***************************************************************************************** 153 * This function creates a new directory in file system. 154 ***************************************************************************************** 155 * @ pathname : pathname (can be relative or absolute). 156 * @ mode : access rights (as defined in chmod). 157 * @ return 0 if success / returns -1 if failure. 158 ****************************************************************************************/ 159 int mkdir( const char * pathname, 160 int mode ); 161 162 /***************************************************************************************** 163 * This function creates a named FIFO file in the calling thread cluster. 164 * The associated read and write file descriptors mut be be explicitely created 165 * using the open() system call. 166 ***************************************************************************************** 167 * @ pathname : pathname (can be relative or absolute). 168 * @ mode : access rights (as defined in chmod). 169 * @ return 0 if success / returns -1 if failure. 170 ****************************************************************************************/ 171 int mkfifo( const char * pathname, 172 int mode ); 173 174 /***************************************************************************************** 175 * This function opens the directory identified by the <pathname> argument, 176 * associates a directory stream with it and returns an user space pointer to identify 177 * this directory stream in subsequent operations. 178 ***************************************************************************************** 179 * @ pathname : pathname (can be relative or absolute). 180 * @ returns DIR* pointer if success / returns NULL if pathname cannot be accessed. 181 ****************************************************************************************/ 182 DIR * opendir( const char * pathname ); 183 184 /***************************************************************************************** 185 * This function returns a pointer to the next directory entry. 186 ***************************************************************************************** 187 * @ dirp : DIR pointer identifying the directory. 188 * @ returns dirent* pointer / returns NULL upon reaching end of directory or on error. 189 ****************************************************************************************/ 190 struct dirent * readdir( DIR * dirp ); 191 192 /***************************************************************************************** 193 * This function closes the directory identified by the <dirp> argument, and releases 194 * all structures associated with the <dirp> pointer. 195 ***************************************************************************************** 196 * @ dirp : DIR pointer identifying the directory. 197 * @ returns 0 if success / returns -1 if failure. 198 ****************************************************************************************/ 199 int closedir( DIR * dirp ); 200 201 /***************************************************************************************** 202 * This function returns the pathname of the current working directory. 203 ***************************************************************************************** 204 * buf : buffer addres in user space. 205 * nbytes : user buffer size in bytes. 206 * @ return 0 if success / returns -1 if failure. 207 ****************************************************************************************/ 208 int getcwd( char * buf, 209 unsigned int nbytes ); 210 211 /***************************************************************************************** 212 * This function removes a directory file whose name is given by <pathname>. 213 * The directory must not have any entries other than `.' and `..'. 214 ***************************************************************************************** 215 * @ pathname : pathname (can be relative or absolute). 216 * @ return 0 if success / returns -1 if failure. 217 ****************************************************************************************/ 218 int rmdir( char * pathname ); 219 220 /***************************************************************************************** 221 * This function implement the operations related to User Thread Local Storage. 222 ***************************************************************************************** 223 * @ operation : UTLS operation type as defined in "shared_sycalls.h" file. 224 * @ value : argument value for the UTLS_SET operation. 225 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure. 226 ****************************************************************************************/ 227 int utls( unsigned int operation, 228 unsigned int value ); 229 230 /***************************************************************************************** 231 * This function change the acces rights for the file/dir identified by the 232 * pathname argument. 233 ***************************************************************************************** 234 * @ pathname : pathname (can be relative or absolute). 235 * @ rights : acces rights. 236 * @ return 0 if success / returns -1 if failure. 237 ****************************************************************************************/ 238 int chmod( char * pathname, 239 unsigned int rights ); 240 241 /***************************************************************************************** 242 * This function associate a specific signal handler to a given signal type. 243 * The handlers for the SIGKILL and SIGSTOP signals cannot be redefined. 244 ***************************************************************************************** 245 * @ sig_id : index defining signal type (from 1 to 31). 246 * @ handler : pointer on fonction implementing the specific handler. 247 * @ return 0 if success / returns -1 if failure. 248 ****************************************************************************************/ 249 int signal( unsigned int sig_id, 250 void * handler ); 251 252 /***************************************************************************************** 253 * This function returns in the structure <tv>, defined in the time.h file, 254 * the current time (in seconds & micro-seconds). 255 * It is computed from the calling core descriptor. 256 * The timezone is not supported. 257 ***************************************************************************************** 258 * @ tv : pointer on the timeval structure. 259 * @ tz : pointer on the timezone structure : must be NULL. 260 * @ return 0 if success / returns -1 if failure. 261 ****************************************************************************************/ 262 int gettimeofday( struct timeval * tv, 263 struct timezone * tz ); 264 265 /***************************************************************************************** 266 * This function implements the "kill" system call on the user side. 267 * It register the signal defined by the <sig_id> argument in all thread descriptors 268 * of a target process identified by the <pid> argument. This is done in all clusters 269 * containing threads for the target process. 270 * It can be executed by any thread running in any cluster, as this function uses 271 * remote access to traverse the list of process copies stored in the owner cluster, 272 * and the RPC_SIGNAL_RISE to signal the remote threads. 273 * This function does nothing for (sig_id == 0). This can be used to check process pid. 274 * TODO : This first implementation supports only SIGKILL / SIGSTOP / SIGCONT values. 275 ***************************************************************************************** 276 * @ pid : target process identifier. 277 * @ sig_id : index defining the signal type. 278 * @ return 0 if success / returns -1 if failure. 279 ****************************************************************************************/ 280 int kill( unsigned int pid, 281 unsigned int sig_id ); 282 283 /***************************************************************************************** 284 * This function implements the "getpid" system call on the user side. 285 ***************************************************************************************** 286 * @ returns the process PID for the calling thread process. 287 ****************************************************************************************/ 288 int getpid(); 289 290 /***************************************************************************************** 291 * This function implement the "fork" system call on the user side. 292 * The calling process descriptor (parent process), and the associated thread descriptor 293 * are replicated in a - likely - remote cluster, that becomes the new process owner. 294 * The child process get a new PID is linked to the parent PID. The child process inherit 295 * from the parent process the memory image, and all open files (including the TXT). 296 * The child process becomes the TXT terminal owner. 297 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be 298 * stored in the calling thread descriptor by the specific fork_place() system call. 299 * If not, the kernel function makes a query to the DQDT to select the target cluster. 300 ***************************************************************************************** 301 * @ if success, returns child process PID to parent, and return O to child. 302 * @ if failure, returns -1 to parent / no child process is created. 303 ****************************************************************************************/ 304 int fork(); 305 306 /***************************************************************************************** 307 * This function implement the "exec" system call on the user side. 308 * It creates, in the same cluster as the calling thread, a new process descriptor, 309 * and a new associated main thread descriptor, executing a new memory image defined 310 * by the <filename> argument. This new process inherit from the old process the PID 311 * and the PPID, as well as all open files (including the TXT). 312 * The old process descriptor, and all its threads are blocked, and marked for deletion. 313 * Therefore the exec syscall does not return to the calling thread in case of success. 314 * This function build an exec_info_t structure containing the new process arguments, 315 * as defined by the <arv> argument, and the new process environment variables, 316 * as defined by the <envp> argument. 317 * TODO : the <argv> and <envp> arguments are not supported yet (both must be NULL). 318 ***************************************************************************************** 319 * @ filename : string pointer on .elf filename (virtual pointer in user space) 320 * @ argv : array of strings on process arguments (virtual pointers in user space) 321 * @ envp : array of strings on environment variables (virtual pointers in user space) 322 * @ does not return if success / returns -1 if failure. 323 ****************************************************************************************/ 324 int exec( char * filename, 325 char ** argv, 326 char ** envp ); 327 328 /***************************************************************************************** 329 * This function returns in the <stat> structure, defined in the "shared_syscalls.h" 330 * file, various informations on the file/directory identified by the <pathname> argument. 331 ***************************************************************************************** 332 * @ pathname : user pointer on file pathname. 333 * @ stat : user pointer on the stat structure. 334 * @ returns O if success / returns -1 if failure. 335 ****************************************************************************************/ 336 int stat( const char * pathname, 337 struct stat * stat ); 338 339 /***************************************************************************************** 340 * This blocking function returns only when one child process of the calling process 341 * changes state (from RUNNING to STOPPED / EXITED / KILLED). It returns the terminating 342 * child process PID, and set in the <status> buffer the new child process state. 343 ***************************************************************************************** 344 * @ status : [out] terminating child process state. 345 * @ returns terminating child process pid. 346 ****************************************************************************************/ 347 int wait( int * status ); 348 349 350 /****************** Non standard (ALMOS_MKH specific) system calls **********************/ 351 352 353 /***************************************************************************************** 354 * This function is used to give the process identified by the <pid> argument the 355 * exclusive ownership of the attached TXT_RX terminal. 356 ***************************************************************************************** 357 * @ pid : process identifier. 358 * @ returns O if success / returns -1 if process not found. 359 ****************************************************************************************/ 360 int fg( unsigned int pid ); 361 362 /*************************************************************************************** 363 * This function returns the hardware platform parameters. 364 *************************************************************************************** 365 * @ x_size : [out] number of clusters in a row. 366 * @ y_size : [out] number of clusters in a column. 367 * @ ncores : [out] number of cores per cluster. 368 * @ return always 0. 369 **************************************************************************************/ 370 int get_config( unsigned int * x_size, 371 unsigned int * y_size, 372 unsigned int * ncores ); 373 374 /*************************************************************************************** 375 * This function returns the cluster an local index for the calling core. 376 *************************************************************************************** 377 * @ cxy : [out] cluster identifier. 378 * @ lid : [out] core local index in cluster. 379 * @ return always 0. 380 **************************************************************************************/ 381 int get_core( unsigned int * cxy, 382 unsigned int * lid ); 383 384 /*************************************************************************************** 385 * This function returns the calling core cycles counter, 386 * taking into account a possible overflow on 32 bits architectures. 387 *************************************************************************************** 388 * @ cycle : [out] current cycle value. 389 * @ return always 0. 390 **************************************************************************************/ 391 int get_cycle( unsigned long long * cycle ); 392 393 /*************************************************************************************** 394 * This debug function displays on the kernel terminal TXT0 395 * the thread / process / core identifiers, the current cycle, plus a user defined 396 * message as specified by the <string> argument. 397 *************************************************************************************** 398 * @ string : [in] user defined message. 399 **************************************************************************************/ 400 void display_string( char * string ); 401 402 /*************************************************************************************** 403 * This debug function displays on the kernel terminal TXT0 404 * the state of the VMM forthe process <pid>, in cluster <cxy>. 405 * It can be called by any thread running in any cluster. 406 *************************************************************************************** 407 * @ pid : [in] process identifier. 408 * @ return 0 if success / return -1 if illegal argument. 409 **************************************************************************************/ 410 int display_vmm( unsigned int cxy, 411 unsigned int pid ); 412 413 /*************************************************************************************** 414 * This debug function displays on the kernel terminal TXT0 415 * the state of the core scheduler identified by the <cxy> and <lid> arguments. 416 * It can be called by any thread running in any cluster. 417 *************************************************************************************** 418 * @ cxy : [in] target cluster identifier. 419 * @ lid : [in] target core local index. 420 * @ return 0 if success / return -1 if illegal arguments. 421 **************************************************************************************/ 422 int display_sched( unsigned int cxy, 423 unsigned int lid ); 424 425 /*************************************************************************************** 426 * This debug function displays on the kernel terminal TXT0 427 * the list of process registered in a given cluster identified by the <cxy> argument. 428 * It can be called by any thread running in any cluster. 429 *************************************************************************************** 430 * @ cxy : [in] target cluster identifier. 431 * @ return 0 if success / return -1 if illegal argument. 432 **************************************************************************************/ 433 int display_cluster_processes( unsigned int cxy ); 434 435 /*************************************************************************************** 436 * This debug function displays on the kernel terminal TXT0 437 * the list of channel devices available in the architecture. 438 * It can be called by any thread running in any cluster. 439 *************************************************************************************** 440 * @ return always 0. 441 **************************************************************************************/ 442 int display_chdev(); 443 444 /*************************************************************************************** 445 * This debug function displays on the kernel terminal TXT0 446 * the list of channel device or pseudo-files registered in the VFS cache. 447 * It can be called by any thread running in any cluster. 448 *************************************************************************************** 449 * @ return always 0. 450 **************************************************************************************/ 451 int display_vfs(); 452 453 /*************************************************************************************** 454 * This debug function displays on the kernel terminal TXT0 455 * the list of processes attached to a given TXT channel. 456 * It can be called by any thread running in any cluster. 457 *************************************************************************************** 458 * @ return always 0. 459 **************************************************************************************/ 460 int display_txt_processes( unsigned int txt_id ); 461 462 /***************************************************************************************** 463 * This debug function is used to activate / desactivate the context switches trace 464 * for a core identified by the <cxy> and <lid> arguments. 465 * It can be called by any thread running in any cluster. 466 ***************************************************************************************** 467 * @ active : activate trace if non zero / desactivate if zero. 468 * @ cxy : cluster identifier. 469 * @ lid : core local index. 470 * @ returns O if success / returns -1 if illegal arguments. 471 ****************************************************************************************/ 472 int trace( unsigned int active, 473 unsigned int cxy, 474 unsigned int lid ); 475 51 /********************************************************************************************* 52 * This function copies a formated string to a fixed size buffer. 53 * it includes the NUL terminating character. 54 * it cheks that the formated string fit in the buffer length. 55 ********************************************************************************************* 56 * @ string : pointer on target buffer. 57 * @ length : max bumber of characters in target buffer. 58 * @ format : formated string. 59 * @ returns number of characters written if success / returns -1 if failure. 60 ********************************************************************************************/ 61 int snprintf( char * string, 62 unsigned int length, 63 const char * format, ... ); 476 64 477 65 #endif // _STDIO_H_ -
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 -
trunk/libs/mini-libc/stdlib.h
r443 r444 25 25 #define _STDLIB_H 26 26 27 # define RAND_MAX 6553528 29 /***************************************************************************************** ****30 * This function te sts the <expression> argument value.31 * When the value is false, it displays an error message, and terminates the calling thread.32 * ********************************************************************************************33 * @ expression : Boolean expression to be checked.34 ********************************************************************************************/ 35 void assert( int expression ); 27 #include <almos-mkh/stdlib.h> 28 29 /***************************************************************************************** 30 * This function terminates a process. 31 ***************************************************************************************** 32 * @ status : terminaison status : 0 / EXIT_SUCCESS / EXIT_FAILURE. 33 ****************************************************************************************/ 34 void exit( int status ); 35 36 36 37 37 /********************************************************************************************* … … 46 46 ********************************************************************************************/ 47 47 double atof(const char *str); 48 49 /*********************************************************************************************50 * This function copies the content of a <src> byte array to a <dst> byte array.51 * Behaviour is undefined if <src> and <dst> arrays overlap.52 *********************************************************************************************53 * @ dst : pointer on destination array.54 * @ dst : pointer on source array.55 * @ size : number of bytes to move.56 * @ return first argument.57 ********************************************************************************************/58 void * memcpy( void * dst,59 const void * src,60 unsigned int size );61 62 /*********************************************************************************************63 * This function fill a byte array with a byte value.64 *********************************************************************************************65 * @ dst : pointer on the byte array.66 * @ s : byte value (will be casted to unsigned char).67 * @ size : number of bytes to be set.68 * @ return first argument.69 ********************************************************************************************/70 void * memset( void * dst,71 int s,72 unsigned int size);73 74 /*********************************************************************************************75 * This function writes a formated string to the standard "stdout" stream.76 *********************************************************************************************77 * @ returns number of characters written if success / returns -1 if failure.78 ********************************************************************************************/79 int printf( const char * format, ... );80 81 /*********************************************************************************************82 * This function returns a positive integer fom the standard "stdin" stream.83 *********************************************************************************************84 * returns the integer value if success / returns -1 if failure.85 ********************************************************************************************/86 int getint();87 88 /*********************************************************************************************89 * This function writes one single character to the standard "stdout" stream.90 *********************************************************************************************91 * @ returns written character code if success / returns 0 (EOF) if failure.92 ********************************************************************************************/93 int putchar( int c );94 95 /*********************************************************************************************96 * This function returns one single character from the standard "stdin" stream.97 *********************************************************************************************98 * @ returns read character code if success / returns 0 (EOF) if failure.99 ********************************************************************************************/100 int getchar();101 102 /*********************************************************************************************103 * This function copies a formated string to a fixed size buffer.104 * it includes the NUL terminating character.105 * it cheks that the formated string fit in the buffer length.106 *********************************************************************************************107 * @ string : pointer on target buffer.108 * @ length : max bumber of characters in target buffer.109 * @ format : formated string.110 * @ returns number of characters written if success / returns -1 if failure.111 ********************************************************************************************/112 int snprintf( char * string,113 unsigned int length,114 const char * format, ... );115 48 116 49 /********************************************************************************************* … … 130 63 int rand(); 131 64 132 /********************************************************************************************* 133 * This blocking function implements an user-level interactive debugger that can be 134 * introduced in any user application to display various kernel distributed structures 135 * related to the calling process. The supported commands are: 136 * - p (cxy) : display all processes descriptors in a given cluster. 137 * - s (cxy,lid) : display all threads attached to a given core in a given cluster. 138 * - v (cxy) : display the calling process VMM in a given cluster. 139 * - t (tid) : display all owner process descriptors attached to a given TXT terminal. 140 * - x : force the calling process to exit. 141 * - c : continue calling process execution. 142 ********************************************************************************************* 143 * @ return an integer value between 0 and RAND_MAX. 144 ********************************************************************************************/ 145 void idbg(); 65 /***************************************************************************************** 66 * This function allocates <size> bytes of memory in user space and returns a pointer 67 * on the allocated buffer. The physical memory is allocated from store located in 68 * the calling core cluster. 69 ***************************************************************************************** 70 * @ size : number of requested bytes. 71 * @ returns a pointer on the allocated buffer if success / returns NULL if failure 72 ****************************************************************************************/ 73 void * malloc( unsigned int size ); 146 74 147 75 76 /***************************************************************************************** 77 * This function releases the memory buffer identified by the <ptr> argument, 78 * to the store located in the calling core cluster. 79 * It displays an error message, but does nothing if the ptr is illegal. 80 ***************************************************************************************** 81 * @ ptr : pointer on the released buffer. 82 ****************************************************************************************/ 83 void free( void * ptr ); 84 85 /***************************************************************************************** 86 * This function releases the memory buffer identified by the <ptr> argument, 87 * to the store located in the calling core cluster, and allocates a new buffer 88 * containing <size> bytes from this store. 89 * The content of the old buffer is copied to the new buffer, up to <size> bytes. 90 * It displays an error message, but does nothing if the ptr is illegal. 91 ***************************************************************************************** 92 * @ ptr : pointer on the released buffer. 93 * @ size : new buffer requested size (bytes). 94 * @ return a pointer on allocated buffer if success / return NULL if failure 95 ****************************************************************************************/ 96 void * realloc( void * ptr, 97 unsigned int size ); 98 99 100 /***************************************************************************************** 101 * This function allocates enough space for <count> objects that are <size> bytes 102 * of memory each from the store located in the calling core cluster. 103 * The allocated memory is filled with bytes of value zero. 104 ***************************************************************************************** 105 * @ count : number of requested objects. 106 * @ size : number of bytes per object. 107 * @ returns a pointer on allocated buffer if success / returns NULL if failure 108 ****************************************************************************************/ 109 void * calloc( unsigned int count, 110 unsigned int size ); 148 111 #endif // _STDLIB_H_ -
trunk/libs/mini-libc/string.c
r439 r444 24 24 #define NULL (void *)0 25 25 26 /////////////////////////// 27 inline int tolower( int c ) 28 { 29 if (c >= 'A' && c <= 'Z') return (c | 0x20); 30 else return c; 31 } 32 33 34 /////////////////////////// 35 inline int toupper( int c ) 36 { 37 if (c >= 'a' && c <= 'z') return (c & ~(0x20)); 38 else return c; 39 } 26 #include <string.h> 40 27 41 28 /////////////////////////////////////// … … 92 79 } 93 80 94 //////////////////////////////////95 int strcasecmp( const char * str1,96 const char * str2 )97 {98 char c1;99 char c2;100 81 101 do102 {103 c1 = (char)toupper( (int)*++str1 );104 c2 = (char)toupper( (int)*++str2 );105 c2 = toupper(*++str2);106 }107 while(c1 && c1 == c2);108 109 return (c1 - c2);110 }111 82 112 83 /////////////////////////// … … 190 161 } 191 162 163 /////////////////////////////////////////////////////////////// 164 void * memcpy(void *_dst, const void * _src, unsigned int size) 165 { 166 unsigned int * dst = _dst; 167 const unsigned int * src = _src; 168 if (!((unsigned int) dst & 3) && !((unsigned int) src & 3) ) 169 { 170 while (size > 3) 171 { 172 *dst++ = *src++; 173 size -= 4; 174 } 175 } 192 176 177 unsigned char *cdst = (unsigned char*)dst; 178 unsigned char *csrc = (unsigned char*)src; 179 180 while (size--) 181 { 182 *cdst++ = *csrc++; 183 } 184 return _dst; 185 } 186 187 ////////////////////////////////////////////////////////// 188 inline void * memset(void * dst, int s, unsigned int size) 189 { 190 char * a = (char *) dst; 191 while (size--) 192 { 193 *a++ = (char)s; 194 } 195 return dst; 196 } 197 198 -
trunk/libs/mini-libc/string.h
r439 r444 69 69 70 70 /******************************************************************************************** 71 * This function compares lexicographically the strings s1 and s2, ignoring case.72 ********************************************************************************************73 * @ s1 : pointer on string.74 * @ s2 : pointer on string.75 * @ return 0 if s1 == s2 / return 1 if s1 > s2 / return -1 if s1 < s276 *******************************************************************************************/77 int strcasecmp ( const char * s1,78 const char * s2 );79 80 /********************************************************************************************81 71 * this function copies the <src> buffer to the <dst> buffer, including the terminating NUL. 82 72 ******************************************************************************************** … … 128 118 int c ); 129 119 130 /********************************************************************************************131 * This function returns a lower case ASCII code if input is in [A...Z] range.132 ********************************************************************************************133 * @ c : the 8 LSB bits define the character to be forced to lower case.134 * @ return lower case ASCII code.135 *******************************************************************************************/136 inline int tolower( int c );137 120 138 /******************************************************************************************** 139 * This function returns an upper case ASCII code if input is in [a...z] range. 140 ******************************************************************************************** 141 * @ c : the 8 LSB bits define the character to be forced to upper case. 142 * @ return upper case ASCII code. 143 *******************************************************************************************/ 144 inline int toupper( int c ); 121 /********************************************************************************************* 122 * This function copies the content of a <src> byte array to a <dst> byte array. 123 * Behaviour is undefined if <src> and <dst> arrays overlap. 124 ********************************************************************************************* 125 * @ dst : pointer on destination array. 126 * @ dst : pointer on source array. 127 * @ size : number of bytes to move. 128 * @ return first argument. 129 ********************************************************************************************/ 130 void * memcpy( void * dst, 131 const void * src, 132 unsigned int size ); 133 134 /********************************************************************************************* 135 * This function fill a byte array with a byte value. 136 ********************************************************************************************* 137 * @ dst : pointer on the byte array. 138 * @ s : byte value (will be casted to unsigned char). 139 * @ size : number of bytes to be set. 140 * @ return first argument. 141 ********************************************************************************************/ 142 void * memset( void * dst, 143 int s, 144 unsigned int size); 145 145 146 146 #endif /* _STRING_H_ */
Note: See TracChangeset
for help on using the changeset viewer.