Changeset 445 for trunk/libs/libalmosmkh
- Timestamp:
- May 29, 2018, 9:27:23 AM (7 years ago)
- Location:
- trunk/libs/libalmosmkh
- Files:
-
- 3 deleted
- 1 edited
- 2 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/libs/libalmosmkh/Makefile
r444 r445 1 1 ############################################################################ 2 # Makefile for the ALMOS-MKH "mini-libc"#2 # Makefile for the ALMOS-MKH specific library # 3 3 ############################################################################ 4 4 5 5 -include ../../params-soft.mk 6 6 7 ifeq ($(ARCH_NAME),) 7 8 $(error Please define in ARCH_NAME parameter in params-soft.mk!) 8 9 endif 9 10 10 SRCS = almos -mkh.c almos-mkh-memory.c11 SRCS = almosmkh.c 11 12 12 13 OBJS = $(addprefix build/, $(SRCS:.c=.o)) \ 13 14 $(HAL_ARCH)/build/core/hal_user.o 14 15 15 INCLUDES = -I. -I$(HAL)/generic -I$(LIBC_INCLUDE) -I$(SHARED_INCLUDE) -I$(LIBPTHREAD_INCLUDE) 16 INCLUDES = -I. \ 17 -I$(LIBC_PATH) \ 18 -I$(LIBPTHREAD_PATH) \ 19 -I$(SHARED_INCLUDE) \ 20 -I$(HAL)/generic \ 21 -I$(HAL_ARCH)/core \ 22 -I$(KERNEL) 16 23 17 libs : build/lib/libalmos -mkh.a build/include/almos-mkh.h24 libs : build/lib/libalmosmkh.a headers 18 25 19 26 build : … … 25 32 $(MAKE) -C $(HAL_ARCH) 26 33 27 28 build/%.o : %.c 34 build/%.o : %.c %.h 29 35 $(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $< 30 36 $(DU) -D $@ > $@.txt 31 37 32 38 headers: build 33 cp almos-mkh.h build/include/. 34 build/lib/libalmos-mkh.a: build $(OBJS) 39 cp $(SRCS:.c=.h) build/include/. 40 41 build/lib/libalmosmkh.a: build $(OBJS) 35 42 $(AR) rc $@ $(OBJS) 36 ranlib$@43 $(RANLIB) $@ 37 44 38 .PHONY = build clean 39 45 .PHONY = build clean headers 40 46 41 47 clean: -
trunk/libs/libalmosmkh/almosmkh.c
r444 r445 1 /* 2 * almosmkh.c - User level ALMOS-MKH specific library implementation. 3 * 4 * Author Alain Greiner (2016,2017,2018) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24 #include <almosmkh.h> 1 25 #include <hal_user.h> 2 #include <almos-mkh.h> 26 #include <hal_types.h> 27 #include <syscalls_numbers.h> 28 #include <string.h> 3 29 #include <stdio.h> 4 #include <syscalls_numbers.h> 5 6 7 #define reg_t int 8 9 ///////////// Non standard system calls //////////////////////////////////// 10 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <mman.h> 33 34 ///////////// Non standard system calls ///////////////////////////////// 11 35 12 36 ////////////////////////// … … 37 61 } 38 62 39 ////////////////////////////////////40 void display_string( char * string )41 {42 hal_user_syscall( SYS_DISPLAY,43 DISPLAY_STRING,44 (reg_t)string, 0, 0 );45 }46 47 ///////////////////////////////////48 int display_vmm( unsigned int cxy, unsigned int pid )49 {50 return hal_user_syscall( SYS_DISPLAY,51 DISPLAY_VMM,52 (reg_t)pid,53 (reg_t)cxy, 0 );54 }55 56 ////////////////////////////////57 int display_sched( unsigned int cxy,58 unsigned int lid )59 {60 return hal_user_syscall( SYS_DISPLAY,61 DISPLAY_SCHED,62 (reg_t)cxy,63 (reg_t)lid, 0 );64 }65 66 /////////////////////////////////////////////////67 int display_cluster_processes( unsigned int cxy )68 {69 return hal_user_syscall( SYS_DISPLAY,70 DISPLAY_CLUSTER_PROCESSES,71 (reg_t)cxy, 0, 0 );72 }73 74 ///////////////////75 int display_chdev()76 {77 return hal_user_syscall( SYS_DISPLAY,78 DISPLAY_CHDEV, 0, 0, 0 );79 }80 81 /////////////////82 int display_vfs()83 {84 return hal_user_syscall( SYS_DISPLAY,85 DISPLAY_VFS, 0, 0, 0 );86 }87 88 ////////////////////////////////////////////////89 int display_txt_processes( unsigned int txt_id )90 {91 return hal_user_syscall( SYS_DISPLAY,92 DISPLAY_TXT_PROCESSES,93 (reg_t)txt_id, 0, 0 );94 }95 96 63 /////////////////////////////////////////// 97 64 int get_cycle( unsigned long long * cycle ) … … 99 66 return hal_user_syscall( SYS_GET_CYCLE, 100 67 (reg_t)cycle, 0, 0, 0 ); 101 }102 103 //////////////////////////////////104 int trace( unsigned int active,105 unsigned int pid,106 unsigned int lid )107 {108 return hal_user_syscall( SYS_TRACE,109 (reg_t)active,110 (reg_t)pid,111 (reg_t)lid, 0 );112 68 } 113 69 … … 120 76 (reg_t)value, 0, 0 ); 121 77 } 122 123 78 124 79 //////////// … … 207 162 } // end getint() 208 163 164 165 /////////////// non standard debug functions ////////////////////////// 166 167 //////////////////////////////////// 168 void display_string( char * string ) 169 { 170 hal_user_syscall( SYS_DISPLAY, 171 DISPLAY_STRING, 172 (reg_t)string, 0, 0 ); 173 } 174 175 /////////////////////////////////// 176 int display_vmm( unsigned int cxy, unsigned int pid ) 177 { 178 return hal_user_syscall( SYS_DISPLAY, 179 DISPLAY_VMM, 180 (reg_t)pid, 181 (reg_t)cxy, 0 ); 182 } 183 184 //////////////////////////////// 185 int display_sched( unsigned int cxy, 186 unsigned int lid ) 187 { 188 return hal_user_syscall( SYS_DISPLAY, 189 DISPLAY_SCHED, 190 (reg_t)cxy, 191 (reg_t)lid, 0 ); 192 } 193 194 ///////////////////////////////////////////////// 195 int display_cluster_processes( unsigned int cxy ) 196 { 197 return hal_user_syscall( SYS_DISPLAY, 198 DISPLAY_CLUSTER_PROCESSES, 199 (reg_t)cxy, 0, 0 ); 200 } 201 202 /////////////////// 203 int display_chdev() 204 { 205 return hal_user_syscall( SYS_DISPLAY, 206 DISPLAY_CHDEV, 0, 0, 0 ); 207 } 208 209 ///////////////// 210 int display_vfs() 211 { 212 return hal_user_syscall( SYS_DISPLAY, 213 DISPLAY_VFS, 0, 0, 0 ); 214 } 215 216 //////////////////////////////////////////////// 217 int display_txt_processes( unsigned int txt_id ) 218 { 219 return hal_user_syscall( SYS_DISPLAY, 220 DISPLAY_TXT_PROCESSES, 221 (reg_t)txt_id, 0, 0 ); 222 } 223 224 ////////////////////////////////// 225 int trace( unsigned int active, 226 unsigned int pid, 227 unsigned int lid ) 228 { 229 return hal_user_syscall( SYS_TRACE, 230 (reg_t)active, 231 (reg_t)pid, 232 (reg_t)lid, 0 ); 233 } 234 235 ////////////////// 236 int display_dqdt() 237 { 238 return hal_user_syscall( SYS_DISPLAY, 239 DISPLAY_DQDT, 0, 0, 0 ); 240 } 241 209 242 /////////// 210 243 void idbg() … … 283 316 284 317 285 318 /////////////// non standard debug functions ////////////////////////// 319 320 #define MALLOC_DEBUG 0 321 322 ///////////////////////////////////////////////////////////////////////////////////////// 323 // Global variable defining the allocator array (one per cluster) 324 // This array (about 16 Kbytes ) will be stored in the data segment 325 // of any application linked with this malloc libray. 326 ///////////////////////////////////////////////////////////////////////////////////////// 327 328 malloc_store_t store[MALLOC_MAX_CLUSTERS]; 329 330 // Macro returning the smallest power of 2 larger or equal to size value 331 332 #define GET_SIZE_INDEX(size) (size <= 0x00000001) ? 0 :\ 333 (size <= 0x00000002) ? 1 :\ 334 (size <= 0x00000004) ? 2 :\ 335 (size <= 0x00000008) ? 3 :\ 336 (size <= 0x00000010) ? 4 :\ 337 (size <= 0x00000020) ? 5 :\ 338 (size <= 0x00000040) ? 6 :\ 339 (size <= 0x00000080) ? 7 :\ 340 (size <= 0x00000100) ? 8 :\ 341 (size <= 0x00000200) ? 9 :\ 342 (size <= 0x00000400) ? 10 :\ 343 (size <= 0x00000800) ? 11 :\ 344 (size <= 0x00001000) ? 12 :\ 345 (size <= 0x00002000) ? 13 :\ 346 (size <= 0x00004000) ? 14 :\ 347 (size <= 0x00008000) ? 15 :\ 348 (size <= 0x00010000) ? 16 :\ 349 (size <= 0x00020000) ? 17 :\ 350 (size <= 0x00040000) ? 18 :\ 351 (size <= 0x00080000) ? 19 :\ 352 (size <= 0x00100000) ? 20 :\ 353 (size <= 0x00200000) ? 21 :\ 354 (size <= 0x00400000) ? 22 :\ 355 (size <= 0x00800000) ? 23 :\ 356 (size <= 0x01000000) ? 24 :\ 357 (size <= 0x02000000) ? 25 :\ 358 (size <= 0x04000000) ? 26 :\ 359 (size <= 0x08000000) ? 27 :\ 360 (size <= 0x10000000) ? 28 :\ 361 (size <= 0x20000000) ? 29 :\ 362 (size <= 0x40000000) ? 30 :\ 363 (size <= 0x80000000) ? 31 :\ 364 32 365 366 //////////////////////////////////////////////////////////////////////////////////////////// 367 // This static function display the current state of the allocator in cluster <cxy>. 368 //////////////////////////////////////////////////////////////////////////////////////////// 369 370 #if 0 371 static void display_free_array( unsigned int cxy ) 372 { 373 unsigned int next; 374 unsigned int id; 375 unsigned int iter; 376 377 printf("\n***** store[%x] base = %x / size = %x\n", 378 cxy , store[cxy].store_base, store[cxy].store_size ); 379 for ( id = 0 ; id < 32 ; id++ ) 380 { 381 next = store[cxy].free[id]; 382 printf(" - free[%d] = " , id ); 383 iter = 0; 384 while ( next != 0 ) 385 { 386 printf("%x | ", next ); 387 next = (*(unsigned int*)next); 388 iter++; 389 } 390 printf("0\n"); 391 } 392 } // end display_free_array() 393 #endif 394 395 396 ////////////////////////////////////////////////////////////////////i////////////////////// 397 // This static function initialises the store in the cluster identified by the <cxy> 398 // arguments. It is called by the malloc() or remote_malloc when a specific store(x,y) 399 // is accessed for the first time by a remote() or remote_malloc() request. 400 // It uses the mmap( MAP_REMOTE ) syscall to allocate a new vseg mapped in cluster (cxy). 401 ////////////////////////////////////////////////////////////////////i////////////////////// 402 // @ cxy : target cluster identifier (fixed format). 403 // @ store_size : store size (bytes). 404 // # return without setting the initialized field in store(cxy) if failure. 405 ////////////////////////////////////////////////////////////////////i////////////////////// 406 static void store_init( unsigned int cxy, 407 unsigned int store_size ) 408 { 409 unsigned int store_base; // store base address 410 unsigned int free_index; // index in free[array] 411 412 unsigned int alloc_base; // alloc[] array base 413 unsigned int alloc_size; // alloc[] array size 414 unsigned int alloc_index; // index in alloc[array] 415 416 unsigned int iter; // iterator 417 418 #if MALLOC_DEBUG 419 printf("\n[MALLOC] %s : enter for store[%x] / size = %x\n", 420 __FUNCTION__, cxy, store_size ); 421 #endif 422 423 // get index in free[] array from size 424 free_index = GET_SIZE_INDEX( store_size ); 425 426 // check store size power of 2 427 if( store_size != (1<<free_index) ) 428 { 429 printf("\n[ERROR] in %s : store[%x] size not power of 2 / size = %x\n", 430 __FUNCTION__, cxy , store_size ); 431 return; 432 } 433 434 // allocate store in virtual space 435 void * vadr = mmap( NULL, // MAP_FIXED not supported 436 store_size, 437 PROT_READ | PROT_WRITE, 438 MAP_REMOTE| MAP_SHARED, 439 cxy, // fd is cluster identifier 440 0 ); // offset unused 441 442 if( vadr == NULL ) 443 { 444 printf("\n[ERROR] in %s : cannot mmap store[%x]\n", 445 __FUNCTION__, cxy ); 446 return; 447 } 448 449 store_base = (unsigned int)vadr; 450 451 // check allocated store alignment 452 if( store_base % store_size ) 453 { 454 printf("\n[ERROR] in %s : store[%x] not aligned / base = %x / size = %x\n", 455 __FUNCTION__, cxy , store_base , store_size ); 456 return; 457 } 458 459 #if MALLOC_DEBUG 460 printf("\n[MALLOC] %s : mmap done for store[%x] / base = %x\n", 461 __FUNCTION__, cxy, store_base ); 462 #endif 463 464 // compute size of block containing alloc[] array 465 alloc_size = store_size / MALLOC_MIN_BLOCK_SIZE; 466 if ( alloc_size < MALLOC_MIN_BLOCK_SIZE) alloc_size = MALLOC_MIN_BLOCK_SIZE; 467 468 // get index for the corresponding block 469 alloc_index = GET_SIZE_INDEX( alloc_size ); 470 471 // compute alloc[] array base address 472 alloc_base = store_base + store_size - alloc_size; 473 474 // reset the free[] array 475 for ( iter = 0 ; iter < 32 ; iter++ ) 476 { 477 store[cxy].free[iter] = 0; 478 } 479 480 // DEPRECATED: we don't reset the alloc_size array 481 // because we don't want to allocate the physical memory 482 // when the heap is created [AG] 483 // memset( (void *)alloc_base , 0 , alloc_size ); 484 485 // split the store into various sizes blocks, 486 // initializes the free[] array and NEXT pointers 487 // base is the block base address 488 unsigned int base = store_base; 489 unsigned int * ptr; 490 for ( iter = free_index-1 ; iter >= alloc_index ; iter-- ) 491 { 492 store[cxy].free[iter] = base; 493 ptr = (unsigned int*)base; 494 *ptr = 0; 495 base = base + (1<<iter); 496 } 497 498 // initialize store mutex 499 if( pthread_mutex_init( &store[cxy].mutex , NULL ) ) 500 { 501 printf("\n[ERROR] in %s : cannot initialize mutex for store[%x]\n", 502 __FUNCTION__, cxy ); 503 return; 504 } 505 506 store[cxy].cxy = cxy; 507 store[cxy].store_base = store_base; 508 store[cxy].store_size = store_size; 509 store[cxy].alloc_size = alloc_size; 510 store[cxy].alloc_base = alloc_base; 511 store[cxy].initialized = MALLOC_INITIALIZED; 512 513 514 #if MALLOC_DEBUG 515 printf("\n[MALLOC] %s : completes store[%x] initialisation\n", 516 __FUNCTION__, cxy ); 517 518 display_free_array( cxy ); 519 #endif 520 521 } // end store_init() 522 523 //////////////////////////////////////////////////////// 524 static unsigned int split_block( malloc_store_t * store, 525 unsigned int vaddr, 526 unsigned int searched_index, 527 unsigned int requested_index ) 528 { 529 // push the upper half block into free[searched_index-1] 530 unsigned int* new = (unsigned int*)(vaddr + (1<<(searched_index-1))); 531 *new = store->free[searched_index-1]; 532 store->free[searched_index-1] = (unsigned int)new; 533 534 if ( searched_index == requested_index + 1 ) // terminal case: return lower half block 535 { 536 return vaddr; 537 } 538 else // non terminal case : lower half block must be split again 539 { 540 return split_block( store, vaddr, searched_index-1, requested_index ); 541 } 542 } // end split_block() 543 544 ////////////////////////////////////////////////////// 545 static unsigned int get_block( malloc_store_t * store, 546 unsigned int searched_index, 547 unsigned int requested_index ) 548 { 549 // test terminal case 550 if ( (1<<searched_index) > store->store_size ) // failure : return a NULL value 551 { 552 return 0; 553 } 554 else // search a block in free[searched_index] 555 { 556 unsigned int vaddr = store->free[searched_index]; 557 if ( vaddr == 0 ) // block not found : search in free[searched_index+1] 558 { 559 return get_block( store, searched_index+1, requested_index ); 560 } 561 else // block found : pop it from free[searched_index] 562 { 563 // pop the block from free[searched_index] 564 unsigned int next = *((unsigned int*)vaddr); 565 store->free[searched_index] = next; 566 567 // test if the block must be split 568 if ( searched_index == requested_index ) // no split required 569 { 570 return vaddr; 571 } 572 else // split is required 573 { 574 return split_block( store, vaddr, searched_index, requested_index ); 575 } 576 } 577 } 578 } // end get_block() 579 580 //////////////////////////////////////// 581 void * remote_malloc( unsigned int size, 582 unsigned int cxy ) 583 { 584 585 #if MALLOC_DEBUG 586 printf("\n[MALLOC] %s : enter for size = %x / cxy = %x\n", 587 __FUNCTION__ , size , cxy ); 588 #endif 589 590 // check arguments 591 if( size == 0 ) 592 { 593 printf("\n[ERROR] in %s : requested size = 0 \n", 594 __FUNCTION__ ); 595 return NULL; 596 } 597 if( cxy >= MALLOC_MAX_CLUSTERS ) 598 { 599 printf("\n[ERROR] in %s : illegal cluster %x\n", 600 __FUNCTION__ , cxy ); 601 return NULL; 602 } 603 604 // initializes target store if required 605 if( store[cxy].initialized != MALLOC_INITIALIZED ) 606 { 607 store_init( cxy , MALLOC_LOCAL_STORE_SIZE ); 608 609 if( store[cxy].initialized != MALLOC_INITIALIZED ) 610 { 611 printf("\n[ERROR] in %s : cannot allocate store in cluster %x\n", 612 __FUNCTION__ , cxy ); 613 return NULL; 614 } 615 } 616 617 // normalize size 618 if ( size < MALLOC_MIN_BLOCK_SIZE ) size = MALLOC_MIN_BLOCK_SIZE; 619 620 // compute requested_index for the free[] array 621 unsigned int requested_index = GET_SIZE_INDEX( size ); 622 623 // take the lock protecting access to store[cxy] 624 pthread_mutex_lock( &store[cxy].mutex ); 625 626 // call the recursive function get_block 627 unsigned int base = get_block( &store[cxy], 628 requested_index, 629 requested_index ); 630 631 // check block found 632 if (base == 0) 633 { 634 pthread_mutex_unlock( &store[cxy].mutex ); 635 printf("\n[ERROR] in %s : no more space in cluster %x\n", 636 __FUNCTION__ , cxy ); 637 return NULL; 638 } 639 640 // compute pointer in alloc[] array 641 unsigned offset = (base - store[cxy].store_base) / MALLOC_MIN_BLOCK_SIZE; 642 unsigned char * ptr = (unsigned char*)(store[cxy].alloc_base + offset); 643 644 // DEPRECATED : we don't check the alloc[] array, 645 // because it has not been initialised, to avoid 646 // physical memory allocation at heap creation [AG] 647 // if ( *ptr != 0 ) 648 // { 649 // pthread_mutex_unlock( &store[cxy].mutex ); 650 // printf("\n[PANIC] in %s : allocate an already allocated block...\n", 651 // __FUNCTION__ ); 652 // return NULL; 653 // } 654 655 // update alloc_array 656 *ptr = requested_index; 657 658 // release the lock 659 pthread_mutex_unlock( &store[cxy].mutex ); 660 661 #if MALLOC_DEBUG 662 printf("\n[MALLOC] %s : exit / base = %x / size = %x / from store[%x]\n", 663 __FUNCTION__, base , size , cxy ); 664 #endif 665 666 return (void*) base; 667 668 } // end remote_malloc() 669 670 671 672 ////////////////////////////////////////// 673 void * remote_calloc ( unsigned int count, 674 unsigned int size, 675 unsigned int cxy ) 676 { 677 void * ptr = remote_malloc( count * size , cxy ); 678 memset( ptr , 0 , count * size ); 679 return ptr; 680 } 681 682 ////////////////////////////////// 683 void * remote_realloc( void * ptr, 684 unsigned int size, 685 unsigned int cxy ) 686 { 687 // simple allocation when (ptr == NULL) 688 if( ptr == NULL ) 689 { 690 return remote_malloc( size , cxy ); 691 } 692 693 // simple free when (size == 0) 694 if( size == 0 ) 695 { 696 remote_free( ptr , cxy ); 697 return NULL; 698 } 699 700 // check cxy and ptr in general case 701 if( cxy >= MALLOC_MAX_CLUSTERS ) 702 { 703 printf("\n[ERROR] in %s : illegal cluster index %x\n", 704 __FUNCTION__ , cxy ); 705 return NULL; 706 } 707 708 unsigned int base = (unsigned int)ptr; 709 710 if( (base < store[cxy].store_base) || 711 (base >= (store[cxy].store_base + store[cxy].store_size)) ) 712 { 713 printf("\n[ERROR] in %s : illegal pointer = %x\n", 714 __FUNCTION__, ptr ); 715 return NULL; 716 } 717 718 // compute index in free[] array 719 int index = (base - store[cxy].store_base) / MALLOC_MIN_BLOCK_SIZE; 720 721 // compute old size 722 char * pchar = (char *) (store[cxy].alloc_base + index); 723 int old_size = 1 << ((int) *pchar); 724 725 // allocate a new block 726 void * new_ptr = remote_malloc( size , cxy ); 727 728 // save old data to new block 729 int min_size = (size < old_size) ? size : old_size; 730 memcpy( new_ptr, ptr, min_size ); 731 732 // release old block 733 remote_free( ptr , cxy ); 734 735 return new_ptr; 736 } 737 738 ////////////////////////////////////////////////////// 739 static void update_free_array( malloc_store_t * store, 740 unsigned int base, 741 unsigned int size_index ) 742 { 743 // This recursive function try to merge the released block 744 // with the companion block if this companion block is free. 745 // This companion has the same size, and almost the same address 746 // (only one address bit is different) 747 // - If the companion is not in free[size_index], 748 // the released block is pushed in free[size_index]. 749 // - If the companion is found, it is evicted from free[size_index] 750 // and the merged bloc is pushed in the free[size_index+1]. 751 752 753 // compute released block size 754 unsigned int size = 1<<size_index; 755 756 // compute companion block and merged block base addresses 757 unsigned int companion_base; 758 unsigned int merged_base; 759 760 if ( (base & size) == 0 ) // the released block is aligned on (2*size) 761 { 762 companion_base = base + size; 763 merged_base = base; 764 } 765 else 766 { 767 companion_base = base - size; 768 merged_base = base - size; 769 } 770 771 // scan all blocks in free[size_index] 772 // the iter & prev variables are actually addresses 773 unsigned int found = 0; 774 unsigned int iter = store->free[size_index]; 775 unsigned int prev = (unsigned int)&store->free[size_index]; 776 while ( iter ) 777 { 778 if ( iter == companion_base ) 779 { 780 found = 1; 781 break; 782 } 783 prev = iter; 784 iter = *(unsigned int*)iter; 785 } 786 787 if ( found == 0 ) // Companion not found => push in free[size_index] 788 { 789 *(unsigned int*)base = store->free[size_index]; 790 store->free[size_index] = base; 791 } 792 else // Companion found : merge 793 { 794 // evict the searched block from free[size_index] 795 *(unsigned int*)prev = *(unsigned int*)iter; 796 797 // call the update_free() function for free[size_index+1] 798 update_free_array( store, merged_base , size_index+1 ); 799 } 800 } // end update_free_array() 801 802 //////////////////////////////////// 803 void remote_free( void * ptr, 804 unsigned int cxy ) 805 { 806 807 #if MALLOC_DEBUG 808 printf("\n[MALLOC] %s : enter for block = %x / cxy = %x\n", 809 __FUNCTION__, ptr, cxy ); 810 #endif 811 812 unsigned int base = (unsigned int)ptr; 813 814 // check cxy value 815 if( cxy >= MALLOC_MAX_CLUSTERS ) 816 { 817 printf("\n[ERROR] in %s : illegal cluster index %x\n", 818 __FUNCTION__ , cxy ); 819 return; 820 } 821 822 // check ptr value 823 if( (base < store[cxy].store_base) || 824 (base >= (store[cxy].store_base + store[cxy].store_size)) ) 825 { 826 printf("\n[ERROR] in %s : illegal pointer for released block = %x\n", 827 __FUNCTION__, ptr ); 828 return; 829 } 830 831 // get the lock protecting store[cxy] 832 pthread_mutex_lock( &store[cxy].mutex ); 833 834 // compute released block index in alloc[] array 835 unsigned index = (base - store[cxy].store_base ) / MALLOC_MIN_BLOCK_SIZE; 836 837 // get the released block size_index 838 unsigned char* pchar = (unsigned char*)(store[cxy].alloc_base + index); 839 unsigned int size_index = (unsigned int)*pchar; 840 841 // check block is allocated 842 if ( size_index == 0 ) 843 { 844 pthread_mutex_unlock( &store[cxy].mutex ); 845 printf("\n[ERROR] in %s : released block not allocated / ptr = %x\n", 846 __FUNCTION__, ptr ); 847 return; 848 } 849 850 // check released block alignment 851 if ( base % (1 << size_index) ) 852 { 853 pthread_mutex_unlock( &store[cxy].mutex ); 854 printf("\n[ERROR] in %s : released block not aligned / ptr = %x\n", 855 __FUNCTION__, ptr ); 856 return; 857 } 858 859 // reset the alloc[index] entry 860 *pchar = 0; 861 862 // call the recursive function update_free_array() 863 update_free_array( &store[cxy], base, size_index ); 864 865 // release the lock 866 pthread_mutex_unlock( &store[cxy].mutex ); 867 868 #if MALLOC_DEBUG 869 printf("\n[MALLOC] %s : conmpletes for block = %x / cxy = %x\n", 870 __FUNCTION__, ptr, cxy ); 871 #endif 872 873 } // end remote_free() 874 875 // Local Variables: 876 // tab-width: 4 877 // c-basic-offset: 4 878 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 879 // indent-tabs-mode: nil 880 // End: 881 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 882 883 884 -
trunk/libs/libalmosmkh/almosmkh.h
r444 r445 1 /* 2 * almosmkh.h - User level ALMOS-MKH specific library definition. 3 * 4 * Author Alain Greiner (2016,2017,2018) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 #ifndef _LIBALMOSMKH_H_ 2 25 #define _LIBALMOSMKH_H_ 3 26 4 #include <almos-mkh/almos-mkh.h> 27 /*************************************************************************************** 28 * various the user level, ALMOS-MKH specific library. It contains: 29 * - non standard system calls. 30 * - debug functions. 31 * - remote malloc extensions. 32 **************************************************************************************/ 33 5 34 #include <pthread.h> 6 7 /****************** Non standard (ALMOS_MKH specific) system calls **********************/ 8 9 10 /***************************************************************************************** 35 #include <shared_almos.h> 36 37 /****************** Non standard (ALMOS_MKH specific) system calls ********************/ 38 39 40 /*************************************************************************************** 11 41 * This function is used to give the process identified by the <pid> argument the 12 42 * exclusive ownership of the attached TXT_RX terminal. 13 *************************************************************************************** **43 *************************************************************************************** 14 44 * @ pid : process identifier. 15 45 * @ returns O if success / returns -1 if process not found. 16 ************************************************************************************** **/46 **************************************************************************************/ 17 47 int fg( unsigned int pid ); 18 48 … … 49 79 50 80 /*************************************************************************************** 81 * This function implement the operations related to User Thread Local Storage. 82 *************************************************************************************** 83 * @ operation : UTLS operation type as defined in "shared_sycalls.h" file. 84 * @ value : argument value for the UTLS_SET operation. 85 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure. 86 **************************************************************************************/ 87 int utls( unsigned int operation, 88 unsigned int value ); 89 90 /*************************************************************************************** 91 * This function returns a positive integer fom the standard "stdin" stream. 92 *************************************************************************************** 93 * returns the integer value if success / returns -1 if failure. 94 **************************************************************************************/ 95 int getint(); 96 97 98 /***************** Non standard (ALMOS-MKH specific) debug functions ******************/ 99 100 101 /*************************************************************************************** 51 102 * This debug function displays on the kernel terminal TXT0 52 103 * the thread / process / core identifiers, the current cycle, plus a user defined … … 91 142 /*************************************************************************************** 92 143 * This debug function displays on the kernel terminal TXT0 144 * the list of processes attached to a given TXT channel. 145 * It can be called by any thread running in any cluster. 146 *************************************************************************************** 147 * @ txt_id : [in] TXT terminal indes. 148 * @ return 0 if success / return -1 if illegal argument. 149 **************************************************************************************/ 150 int display_txt_processes( unsigned int txt_id ); 151 152 /*************************************************************************************** 153 * This debug function displays on the kernel terminal TXT0 93 154 * the list of channel devices available in the architecture. 94 155 * It can be called by any thread running in any cluster. … … 108 169 109 170 /*************************************************************************************** 110 * This debug function displays on the kernel terminal TXT0 111 * the list of processes attached to a given TXT channel. 112 * It can be called by any thread running in any cluster. 113 *************************************************************************************** 114 * @ return always 0. 115 **************************************************************************************/ 116 int display_txt_processes( unsigned int txt_id ); 171 * This debug function displays on the kernel terminal TXT0 the current DQDT state. 172 * It can be called by any thread running in any cluster. 173 *************************************************************************************** 174 * @ return always 0. 175 **************************************************************************************/ 176 int display_dqdt(); 117 177 118 178 /***************************************************************************************** … … 126 186 * @ returns O if success / returns -1 if illegal arguments. 127 187 ****************************************************************************************/ 128 129 188 int trace( unsigned int active, 130 189 unsigned int pid, 131 190 unsigned int trdid ); 132 191 133 /***************************************************************************************** 134 * This function implement the operations related to User Thread Local Storage. 135 ***************************************************************************************** 136 * @ operation : UTLS operation type as defined in "shared_sycalls.h" file. 137 * @ value : argument value for the UTLS_SET operation. 138 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure. 139 ****************************************************************************************/ 140 int utls( unsigned int operation, 141 unsigned int value ); 142 143 /********************************************************************************************* 144 * This function returns a positive integer fom the standard "stdin" stream. 145 ********************************************************************************************* 146 * returns the integer value if success / returns -1 if failure. 147 ********************************************************************************************/ 148 int getint(); 149 150 151 /////// Non-standard memory operations //////////// 152 //////////////////////////////////////////////////////////////////////////////// 192 /**************************************************************************************** 193 * This blocking function implements an user-level interactive debugger that can be 194 * introduced in any user application to display various kernel distributed structures. 195 * The supported commands are: 196 * - p (cxy) : display all processes descriptors in a given cluster. 197 * - s (cxy,lid) : display all threads attached to a given core in a given cluster. 198 * - v (cxy) : display the calling process VMM in a given cluster. 199 * - t (tid) : display all owner process descriptors attached to a TXT terminal. 200 * - x : force the calling process to exit. 201 * - c : continue calling process execution. 202 * - h : list the supported commands 203 ***************************************************************************************/ 204 void idbg(); 205 206 207 /****************** Non standard (ALMOS-MKH specific) malloc operations ***************/ 208 209 ///////////////////////////////////////////////////////////////////////////////////////// 153 210 // General principles: 154 211 // - In user space the HEAP zone spread between the ELF zone and the STACK zone, … … 168 225 // We should introduce the possibility to dynamically allocate 169 226 // several vsegs in each cluster, using several mmap when required. 170 //////////////////////////////////////////////////////////////////////////////// 227 ///////////////////////////////////////////////////////////////////////////////////////// 171 228 // Free blocks organisation in each cluster : 172 229 // - All free blocks have a size that is a power of 2, larger or equal … … 179 236 // - The pointers on the first free block for each size are stored in an 180 237 // array of pointers free[32] in the storage(x,y) descriptor. 181 //////////////////////////////////////////////////////////////////////////////// 238 ///////////////////////////////////////////////////////////////////////////////////////// 182 239 // Allocation policy: 183 240 // - The block size required by the user can be any value, but the allocated … … 200 257 // If the vseg is aligned (the vseg base is a multiple of the 201 258 // vseg size), all allocated blocks are aligned on the actual_size. 202 //////////////////////////////////////////////////////////////////////////////// 259 ///////////////////////////////////////////////////////////////////////////////////////// 203 260 // Free policy: 204 261 // - Each allocated block is registered in an alloc[] array of unsigned char. … … 213 270 // - The alloc[] array is stored at the end of heap segment. This consume 214 271 // (1 / MALLOC_MIN_BLOCK_SIZE) of the total storage capacity. 215 //////////////////////////////////////////////////////////////////////////////// 272 ///////////////////////////////////////////////////////////////////////////////////////// 216 273 217 274 … … 221 278 #define MALLOC_MAX_CLUSTERS 0x100 // 256 clusters 222 279 223 //////////////////////////////////////////////////////////////////////////////// 224 // store(x,y) descriptor (one per cluster)225 //////////////////////////////////////////////////////////////////////////////// 280 ///////////////////////////////////////////////////////////////////////////////////////// 281 // store(x,y) descriptor (one per cluster) 282 ///////////////////////////////////////////////////////////////////////////////////////// 226 283 227 284 typedef struct malloc_store_s 228 285 { 229 pthread_mutex_t mutex; // lock protecting exclusive access 286 pthread_mutex_t mutex; // lock protecting exclusive access to local heap 230 287 unsigned int initialized; // initialised when value == MALLOC_INITIALIZED 231 288 unsigned int cxy; // cluster identifier … … 276 333 unsigned int size, 277 334 unsigned int cxy ); 335 278 336 /***************************************************************************************** 279 337 * This function allocates enough space for <count> objects that are <size> bytes … … 290 348 unsigned int cxy ); 291 349 292 /*********************************************************************************************293 * This blocking function implements an user-level interactive debugger that can be294 * introduced in any user application to display various kernel distributed structures295 * related to the calling process. The supported commands are:296 * - p (cxy) : display all processes descriptors in a given cluster.297 * - s (cxy,lid) : display all threads attached to a given core in a given cluster.298 * - v (cxy) : display the calling process VMM in a given cluster.299 * - t (tid) : display all owner process descriptors attached to a given TXT terminal.300 * - x : force the calling process to exit.301 * - c : continue calling process execution.302 *********************************************************************************************303 * @ return an integer value between 0 and RAND_MAX.304 ********************************************************************************************/305 void idbg();306 307 350 #endif /* _LIBALMOSMKH_H_ */ 308 351
Note: See TracChangeset
for help on using the changeset viewer.