Ignore:
Timestamp:
May 29, 2018, 9:27:23 AM (4 years ago)
Author:
alain
Message:

Restructure the mini_libc.

Location:
trunk/libs/libalmosmkh
Files:
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • 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>
    125#include <hal_user.h>
    2 #include <almos-mkh.h>
     26#include <hal_types.h>
     27#include <syscalls_numbers.h>
     28#include <string.h>
    329#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    /////////////////////////////////
    1135
    1236//////////////////////////
     
    3761}
    3862
    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 
    9663///////////////////////////////////////////
    9764int get_cycle( unsigned long long * cycle )
     
    9966    return hal_user_syscall( SYS_GET_CYCLE,
    10067                             (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 );
    11268}
    11369
     
    12076                             (reg_t)value, 0, 0 );
    12177}
    122 
    12378
    12479////////////
     
    207162}  // end getint()
    208163
     164
     165///////////////    non standard debug functions    //////////////////////////
     166
     167////////////////////////////////////
     168void display_string( char * string )
     169{
     170    hal_user_syscall( SYS_DISPLAY,
     171                      DISPLAY_STRING,
     172                      (reg_t)string, 0, 0 );
     173}
     174
     175///////////////////////////////////
     176int 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////////////////////////////////
     185int 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/////////////////////////////////////////////////
     195int 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///////////////////
     203int display_chdev()
     204{
     205    return hal_user_syscall( SYS_DISPLAY,
     206                             DISPLAY_CHDEV, 0, 0, 0 );
     207}
     208
     209/////////////////
     210int display_vfs()
     211{
     212    return hal_user_syscall( SYS_DISPLAY,
     213                             DISPLAY_VFS, 0, 0, 0 );
     214}
     215
     216////////////////////////////////////////////////
     217int 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//////////////////////////////////
     225int 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//////////////////
     236int display_dqdt()
     237{
     238    return hal_user_syscall( SYS_DISPLAY,
     239                             DISPLAY_DQDT, 0, 0, 0 );
     240}
     241
    209242///////////
    210243void idbg()
     
    283316
    284317
    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
     328malloc_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
     371static 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//////////////////////
     406static 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
     419printf("\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
     460printf("\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
     515printf("\n[MALLOC] %s : completes store[%x] initialisation\n",
     516__FUNCTION__, cxy );
     517
     518display_free_array( cxy );
     519#endif
     520
     521}  // end store_init()
     522
     523////////////////////////////////////////////////////////
     524static 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//////////////////////////////////////////////////////
     545static 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////////////////////////////////////////
     581void * remote_malloc( unsigned int size,
     582                      unsigned int cxy )
     583{
     584
     585#if MALLOC_DEBUG
     586printf("\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
     662printf("\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//////////////////////////////////////////
     673void * 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//////////////////////////////////
     683void * 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//////////////////////////////////////////////////////
     739static 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////////////////////////////////////
     803void remote_free( void        * ptr,
     804                  unsigned int  cxy )
     805{
     806
     807#if MALLOC_DEBUG
     808printf("\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
     869printf("\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
Note: See TracChangeset for help on using the changeset viewer.