Changeset 8953

Show
Ignore:
Timestamp:
07/15/11 11:28:59 (23 months ago)
Author:
jdenton
Message:

Updates to memory entry functions.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/Orange-Branch/src/client/usrint/ucache.c

    r8938 r8953  
    108108        { 
    109109                mtbl->mem[i].item = NIL; 
     110                mtbl->mem[i].tag = NIL; 
     111                mtbl->mem[i].next = NIL; 
     112                mtbl->mem[i].lru_prev = NIL; 
     113                mtbl->mem[i].lru_next = NIL; 
    110114        } 
    111115        /* set up list of free hash table entries */ 
     
    121125{ 
    122126        struct file_table_s *ftbl = &(ucache->ftbl); 
    123         uint32_t ret = ftbl->free_blk; 
    124         if((int32_t)ret!=NIL){ 
     127        uint32_t free_blk = ftbl->free_blk; 
     128        if((int32_t)free_blk!=NIL){ 
    125129                /* Use zero since free_blks have no ititialized mem tables */ 
    126                 ftbl->free_blk = ucache->b[ret].mtbl[0].free_list;  
    127                 return ret; 
     130                ftbl->free_blk = ucache->b[free_blk].mtbl[0].free_list;  
     131                return free_blk; 
    128132        } 
    129133        else{ 
     
    135139static void put_free_blk(int blk) 
    136140{ 
     141        if(DBG)fprintf(out, "freeing blk @ index = %d\n", blk); 
    137142        struct file_table_s *ftbl = &(ucache->ftbl); 
    138143        ucache->b[blk].mtbl[0].free_list = ftbl->free_blk; 
     
    155160        } 
    156161        else{ 
    157                 /*      EVICT?  */ 
    158162                if(DBG)fprintf(out, "\terror getting free file entry...\n"); 
    159163                return NIL; 
     
    188192        if((int16_t)ret!=NIL){ 
    189193                mtbl->free_list = mtbl->mem[ret].next; 
     194                mtbl->mem[ret].next = NIL; 
     195                mtbl->mem[ret].lru_prev = NIL; 
     196                mtbl->mem[ret].lru_next = NIL; 
    190197                return ret; 
    191198        } 
    192199        else{ 
    193                 /*      EVICT?  */ 
     200                /*      EVICT LRU       */ 
    194201                return NIL; 
    195202        } 
     
    198205static void put_free_ment(struct mem_table_s *mtbl, int ent) 
    199206{ 
    200         mtbl->mem[ent].next = mtbl->free_list; 
    201         mtbl->free_list = ent; 
     207        if(DBG)fprintf(out, "freeing memory entry = %d\n", ent); 
     208        /*      Reset ment values       */ 
     209        mtbl->mem[ent].tag = NIL; 
     210        mtbl->mem[ent].item = NIL; 
     211        mtbl->mem[ent].dirty_next = NIL; 
     212        mtbl->mem[ent].lru_next = NIL; 
     213        mtbl->mem[ent].lru_prev = NIL; 
     214        /*      Update free list to include this entry  */ 
     215        if(ent>(MEM_TABLE_HASH_MAX-1)){ 
     216                mtbl->mem[ent].next = mtbl->free_list; 
     217                mtbl->free_list = ent; 
     218        } 
    202219} 
    203220 
     
    292309        uint32_t free_mtbl_blk; 
    293310        uint16_t free_mtbl_ent;  
    294         /*      Create fre mtbls if none are available  */ 
     311        /*      Create free mtbls if none are available */ 
    295312        if(get_next_free_mtbl(&free_mtbl_blk, &free_mtbl_ent)!=1){ 
    296313                /*      Attempt to intitialize remaining blocks' memory tables  */ 
     
    299316                        add_free_mtbls(ucache->ftbl.free_blk); 
    300317                        get_next_free_mtbl(&free_mtbl_blk, &free_mtbl_ent); 
    301                         //continue 
    302318                } 
    303319                else{ 
     
    319335                        /*      point new head's "next" to former head  */ 
    320336                        current->next = free_fent;       
    321                         //if(DBG)fprintf(out, "\tnew head's next = %d\n", (int16_t)current->next); 
    322337                } 
    323338                else{   /*      No free file entries available: policy? */ 
     339                        if(DBG)fprintf(out, "\terror: no free file entries\n"); 
    324340                        /*      Evict or return NIL     */ 
    325                         if(DBG)fprintf(out, "\terror: no free file entries"); 
    326                         return (struct mem_table_s *)NIL; 
     341                        if(F_EVICT){    /*      EVICT   */ 
     342                                uint16_t temp_ndx = current->next; 
     343                                current = &(ftbl->file[current->next]); 
     344                                uint16_t next = current->next; 
     345                                put_free_fent(temp_ndx); 
     346                                /*      May need to do more here        ...mtbls?*/ 
     347                                free_fent = get_free_fent(); 
     348                                current = &(ftbl->file[free_fent]); 
     349                                current->next = next; 
     350                        } 
     351                        else{   /*      Return NIL      */ 
     352                                return (struct mem_table_s *)NIL; 
     353                        } 
     354 
     355 
    327356                } 
    328357        } 
     
    364393        uint32_t tmp_blk = ftbl->free_mtbl_blk; 
    365394        uint16_t tmp_ent = ftbl->free_mtbl_ent; 
    366  
    367395        /*      newly free mtbl becomes new head of free mtbl list      */ 
    368396        ftbl->free_mtbl_blk = file_mtbl_blk; 
    369397        ftbl->free_mtbl_ent = file_mtbl_ent; 
    370  
    371398        /* Point to the next free mtbl (the former head)        */ 
    372399        mtbl->free_list_blk = tmp_blk; 
    373400        mtbl->free_list = tmp_ent; 
    374          
    375401        /*      Free the file entry     */ 
    376402        ftbl->file[file_ent_prev_index].next = ftbl->file[file_ent_index].next; 
    377         put_free_fent(file_ent_index);  //not okay restore links 
     403        put_free_fent(file_ent_index); 
    378404        if(DBG)fprintf(out, "\tremoval sucessful\n"); 
    379         //print the values to ensure they really got set 
    380         //if(DBG)fprintf(out, "\ttag_id\t\t0X%X\n", ftbl->file[file_ent_index].tag_id); 
    381         //if(DBG)fprintf(out, "\ttag_handle\t0X%llX\n", ftbl->file[file_ent_index].tag_handle); 
    382405        return(1); 
    383406} 
    384407 
    385 static void *lookup_mem(struct mem_table_s *mtbl, uint64_t offset) 
    386 { 
     408static void *lookup_mem(struct mem_table_s *mtbl,  
     409                                        uint64_t offset,  
     410                                        uint32_t *item_index, 
     411                                        uint16_t *mem_ent_index, 
     412                                        uint16_t *mem_ent_prev_index) 
     413{ 
     414        if(DBG)fprintf(out, "performing ment lookup...\n"); 
     415        /*      index into mem hash table       */ 
     416        unsigned int index = offset % MEM_TABLE_HASH_MAX; 
     417        if(DBG)fprintf(out, "\toffset: 0X%llX hashes to index: %u\n", offset, index); 
     418        struct mem_ent_s *current = &(mtbl->mem[index]); 
     419        int16_t p,c,n;  /*      previous, current, next memory entry index in mtbl      */ 
     420        p = NIL; c = index; n = current->next; 
     421        while(1){ 
     422                //if(DBG)fprintf(out, "\tp=%d\tc=%d\tn=%d\n", (int)p, (int)c, (int)n); 
     423                //tags match? 
     424                if(offset==current->tag){ 
     425                        if(DBG)fprintf(out, "\tmatch located: 0X%llX==0X%llX\n", offset, current->tag); 
     426                        //possibly update LRU list based on lookup? 
     427                         
     428                        /*      If params !NULL, set their values       */ 
     429                        if(item_index!=NULL && mem_ent_index!=NULL &&  
     430                                mem_ent_prev_index!=NULL){ 
     431                                        *item_index = current->item; 
     432                                        *mem_ent_index = c; 
     433                                        *mem_ent_prev_index = p; 
     434                        } 
     435                        return (void *)(&ucache->b[current->item].mblk); 
     436                } 
     437                else{ 
     438                        //if(DBG)fprintf(out, "\t0X%llX!=0X%llX\n", offset, current->tag); 
     439                        //if next available iterate 
     440                        if((int16_t)current->next==NIL){ 
     441                                if(DBG)fprintf(out, "\tmemory entry not found\n"); 
     442                                return (struct mem_table_s *)NIL; 
     443                        } 
     444                        else{ 
     445                                //fprintf(out, "\tnext really not null: %d!=-1\n", (int)(current->next));  
     446                                current = &(mtbl->mem[current->next]); 
     447                                p=c; c=n; n=current->next; 
     448                                //if(DBG)fprintf(out, "\titerating across chain: next index = %d\n", (int16_t)n); 
     449                        } 
     450                } 
     451        } 
     452} 
     453 
     454 
     455void print_lru(struct mem_table_s *mtbl){ 
     456        if(DBG)fprintf(out, "\tno ment\n"); 
     457        if(DBG)fprintf(out, "\tprinting lru list:\n"); 
     458        if(DBG)fprintf(out, "\t\tlru: %d\n", (int16_t)mtbl->lru_last); 
     459        uint16_t current= mtbl->lru_last;  
     460        while((int16_t)current!=NIL){ 
     461                current = mtbl->mem[current].lru_prev; 
     462                if(DBG)fprintf(out, "\t\tprev: %d\n", (int16_t)current);  
     463        } 
     464} 
     465 
     466void update_lru(struct mem_table_s *mtbl,  
     467                                        uint16_t index){ 
     468                        if(DBG)fprintf(out, "updating lru...\n"); 
     469                        if((int16_t)index<MEM_TABLE_HASH_MAX){ 
     470                                if(DBG)fprintf(out, "\t%d<MEM_TABLE_HASH_MAX, not adding to LRU\n", index); 
     471                                return; 
     472                        } 
     473                        /*      update LRU List */ 
     474                        if((int16_t)mtbl->lru_first==NIL && (int16_t)mtbl->lru_last==NIL){ 
     475                                if(DBG)fprintf(out, "\tsetting lru first and last\n"); 
     476                                mtbl->lru_first = index; 
     477                                mtbl->lru_last = index; 
     478                                mtbl->mem[index].lru_prev = NIL; 
     479                                mtbl->mem[index].lru_next = NIL; 
     480                        } 
     481                        else if(mtbl->lru_first==mtbl->lru_last){ 
     482                                if(mtbl->lru_first!=index){//if not already the first and last 
     483                                        if(DBG)fprintf(out, "\tinserting second record in LRU\n"); 
     484                                        mtbl->mem[mtbl->lru_last].lru_prev = index;     //point tail.prev to new 
     485                                        mtbl->mem[index].lru_prev = NIL;                        //point new.prev to nil 
     486                                        mtbl->mem[index].lru_next = mtbl->lru_last;     //point the new.next to the tail 
     487                                        mtbl->lru_first = index;                                        //point the head to the new 
     488                                } 
     489                        } 
     490                        else{ 
     491                                if(DBG)fprintf(out, "\trepairing previous LRU links and inserting record in LRU\n"); 
     492                                /*      repair links    */       
     493                                if((int16_t)mtbl->mem[index].lru_prev!=NIL){ 
     494                                        mtbl->mem[mtbl->mem[index].lru_prev].lru_next =  
     495                                                mtbl->mem[index].lru_next; 
     496                                } 
     497                                if((int16_t)mtbl->mem[index].lru_next!=NIL){ 
     498                                        mtbl->mem[mtbl->mem[index].lru_next].lru_prev =          
     499                                                mtbl->mem[index].lru_prev; 
     500                                } 
     501                                /*      update nodes own link   */ 
     502                                mtbl->mem[mtbl->lru_first].lru_prev = index;  
     503                                mtbl->mem[index].lru_next = mtbl->lru_first; 
     504                                mtbl->mem[index].lru_prev = NIL; 
     505                        /*      Finally, establish this entry as the first on lru       */ 
     506                                mtbl->lru_first = index; 
     507                        } 
     508} 
     509 
     510/*      Set the block index where data is stored        */ 
     511static void *set_item(struct mem_table_s *mtbl,  
     512                                        uint64_t offset,  
     513                                        uint16_t index){         
     514                int free_blk = get_free_blk(); 
     515                if(free_blk!=NIL){      /*      got block       */ 
     516                        /*      increment num_blocks used by this mtbl  */ 
     517                        mtbl->num_blocks++; 
     518                        update_lru(mtbl, index); 
     519                        if(DBG)fprintf(out, "\tsuccessfully inserted into ment\n"); 
     520                        /*      set item to block number        */ 
     521                        mtbl->mem[index].tag = offset; 
     522                        mtbl->mem[index].item = free_blk; 
     523                        return (void *)&(ucache->b[free_blk]);  
     524                } 
     525                else{   /*      NIL     */ 
     526                        if(DBG)fprintf(out, "\tno blk\n"); 
     527                        return (void *)NIL; 
     528                } 
    387529} 
    388530 
    389531static void *insert_mem(struct mem_table_s *mtbl, uint64_t offset) 
    390532{ 
     533        if(DBG)fprintf(out, "trying to insert mem...\n"); 
     534        /*      index into mem hash table       */ 
     535        unsigned int index = offset % MEM_TABLE_HASH_MAX; 
     536        if(DBG)fprintf(out, "\toffset: 0X%llX hashes to index: %u\n", offset, index); 
     537        struct mem_ent_s *current = &(mtbl->mem[index]); 
     538        /*      lookup first    */ 
     539        void *returnValue = lookup_mem(mtbl, offset, NULL, NULL, NULL); 
     540        if((int)returnValue!=NIL){ 
     541                if(DBG)fprintf(out, "\tblock for this offset already exists @ 0X%X", (unsigned int)returnValue); 
     542                return returnValue; 
     543        } 
     544        if(DBG)fprintf(out, "\tlookup returned NIL\n"); 
     545        if((int64_t)mtbl->mem[index].tag!=NIL){ /*      if head occupied, need to get free ment */ 
     546                int mentIndex = get_free_ment(mtbl); 
     547                if(mentIndex==NIL){     /*      no free memory entry available  */ 
     548                        //print_lru(mtbl); 
     549                        uint16_t lru = mtbl->lru_last;   
     550                        if(DBG)fprintf(out, "evicting memory entry = %d\n", lru); 
     551                        remove_mem(mtbl, mtbl->mem[lru].tag);   /*      evict LRU ment  */ 
     552                        mentIndex = get_free_ment(mtbl);                /*      try to get ment again */ 
     553 
     554                } 
     555                if(mentIndex!=NIL){ 
     556                        if(DBG)fprintf(out, "\tfound free memory entry @ index = %d\n", mentIndex); 
     557                        /*      insert after head of chain      */ 
     558                        uint16_t next_ment = current->next; 
     559                        current->next = mentIndex; 
     560                        mtbl->mem[mentIndex].next = next_ment; 
     561                        return set_item(mtbl, offset, mentIndex);        
     562                } 
     563        } 
     564        else{   /*      No need to iterate to next in chain, just use head      */ 
     565                return set_item(mtbl, offset, index);                                    
     566        } 
    391567} 
    392568 
    393569static int remove_mem(struct mem_table_s *mtbl, uint64_t offset) 
    394570{ 
    395 } 
    396  
    397 /* externally visible API */ 
    398 #if 0 
    399 int ucache_open_file(PVFS_object_ref *handle) 
    400 { 
    401 } 
    402  
    403 void *ucache_lookup(PVFS_object_ref *handle, uint64_t offset) 
    404 { 
    405 } 
    406  
    407 void *ucache_insert(PVFS_object_ref *handle, uint64_t offset) 
    408 { 
    409 } 
    410  
    411 int ucache_remove(PVFS_object_ref *handle, uint64_t offset) 
    412 { 
    413 } 
    414  
    415 int ucache_flush(PVFS_object_ref *handle) 
    416 { 
    417 } 
    418  
    419 int ucache_close_file(PVFS_object_ref *handle) 
    420 { 
    421 } 
    422 #endif 
     571        if(DBG)fprintf(out, "trying to remove memory entry...\n"); 
     572        //some indexes... 
     573        int32_t item_index; 
     574        int16_t mem_ent_index; 
     575        int16_t mem_ent_prev_index; 
     576 
     577        void *retValue = lookup_mem(mtbl, offset, &item_index, &mem_ent_index, &mem_ent_prev_index); 
     578 
     579        /*      Verify we've recieved the necessary info        */ 
     580        if((int)retValue==NIL){ 
     581                if(DBG)fprintf(out, "\tremoval error: memory entry not found matching offset"); 
     582                return NIL; 
     583        } 
     584 
     585        /*      Remove from LRU */ 
     586                /*      update each of adjacent nodes' link     */ 
     587        if((int16_t)mtbl->mem[mem_ent_index].lru_prev!=NIL){ 
     588                mtbl->mem[mtbl->mem[mem_ent_index].lru_prev].lru_next = mtbl->mem[mem_ent_index].lru_next; 
     589        } 
     590        if((int16_t)mtbl->mem[mem_ent_index].lru_next!=NIL){ 
     591                mtbl->mem[mtbl->mem[mem_ent_index].lru_next].lru_prev = mtbl->mem[mem_ent_index].lru_prev; 
     592        } 
     593 
     594        if(mem_ent_index==mtbl->lru_first){ /* is node the head */ 
     595                mtbl->lru_first = mtbl->mem[mem_ent_index].lru_next;     
     596        } 
     597        if(mem_ent_index==mtbl->lru_last){ /* is node the tail */ 
     598                mtbl->lru_last = mtbl->mem[mem_ent_index].lru_prev; 
     599        } 
     600        /*      Remove from Dirty if Dirty      */ 
     601 
     602        /*      add memory block back to free list      */ 
     603        put_free_blk(item_index); 
     604         
     605        /*      Repair link     */ 
     606        if((int16_t)mem_ent_prev_index!=NIL){ 
     607                mtbl->mem[mem_ent_prev_index].next = mtbl->mem[mem_ent_index].next; 
     608        } 
     609        /*      newly free mem entry becomes new head of free mem entry list if less than hash table max        */ 
     610        put_free_ment(mtbl, mem_ent_index); 
     611        mtbl->num_blocks--; 
     612        if(DBG)fprintf(out, "\tmemory entry removal sucessful\n"); 
     613        return(1); 
     614} 
     615