Changeset 616:2a0cd6574d1c

Show
Ignore:
Timestamp:
06/14/08 17:07:24 (7 months ago)
Author:
Maxime Petazzoni <maxime.petazzoni@…>
Branch:
default
Message:

Working on the defrag_for_file() method.

Location:
nxos
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • nxos/base/drivers/_efc.c

    r613 r616  
    2020 
    2121#define EFC_WRITE ((EFC_WRITE_KEY << 24) + EFC_CMD_WP) 
    22 #define EFC_THROTTLE_TIMER 1 
     22#define EFC_THROTTLE_TIMER 2 
    2323 
    2424void nx__efc_init(void) { 
  • nxos/base/lib/fs/fs.c

    r614 r616  
    210210 
    211211  while (len--) { 
    212     memcpy((void *) data, 
    213            (void *) &(FLASH_BASE_PTR[source*EFC_PAGE_WORDS]), 
    214            EFC_PAGE_BYTES); 
     212    nx__efc_read_page(source, data); 
     213 
    215214    if (!nx__efc_write_page(data, dest)) { 
    216215      return FS_ERR_FLASH_ERROR; 
     
    232231 
    233232  while (len--) { 
    234     memcpy((void *) data, 
    235            (void *) &(FLASH_BASE_PTR[(source + len)*EFC_PAGE_WORDS]), 
    236            EFC_PAGE_BYTES); 
     233    nx__efc_read_page(source + len, data); 
     234 
    237235    if (!nx__efc_write_page(data, dest + len)) { 
    238236      return FS_ERR_FLASH_ERROR; 
     
    306304  if (nx_fs_find_last_origin(&origin) == FS_ERR_NO_ERROR) { 
    307305    origin += nx_fs_get_file_page_count( 
    308                 nx_fs_get_file_size_from_metadata( 
    309                   &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
     306        nx_fs_get_file_size_from_metadata( 
     307          &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
    310308 
    311309    if (size < FS_PAGE_END - origin) { 
     
    321319 
    322320    start = origin + nx_fs_get_file_page_count( 
    323                 nx_fs_get_file_size_from_metadata( 
    324                   &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
     321        nx_fs_get_file_size_from_metadata( 
     322          &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
    325323  } 
    326324 
     
    389387  if (nx_fs_find_last_origin(&origin) == FS_ERR_NO_ERROR) { 
    390388    origin += nx_fs_get_file_page_count( 
    391                 nx_fs_get_file_size_from_metadata( 
    392                   &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
     389        nx_fs_get_file_size_from_metadata( 
     390          &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]))); 
    393391  } else { 
    394      origin = FS_PAGE_START; 
     392    origin = FS_PAGE_START; 
    395393  } 
    396394 
     
    425423  /* First, make sure we have an avaliable slot for this file. */ 
    426424  while (slot < FS_MAX_OPENED_FILES && fdset[slot].used) { 
    427    slot++; 
     425    slot++; 
    428426  } 
    429427 
     
    551549   */ 
    552550  if (file->wbuf.pos == 0 && 
    553     file->wbuf.page > file->origin + pages && 
    554     nx_fs_page_has_magic(file->wbuf.page)) { 
     551      file->wbuf.page > file->origin + pages && 
     552      nx_fs_page_has_magic(file->wbuf.page)) { 
    555553    /* If the page we want to use is not available relocate the file. */ 
    556554    err = nx_fs_relocate(file); 
     
    579577  if (file->wbuf.page == file->origin + pages) { 
    580578    if (file->wbuf.pos > file->size + FS_FILE_METADATA_BYTES 
    581       - (pages * EFC_PAGE_BYTES)) { 
     579        - (pages * EFC_PAGE_BYTES)) { 
    582580      file->size++; 
    583581    } 
     
    748746 
    749747void nx_fs_get_occupation(U32 *files, U32 *used, U32 *free_pages, 
    750                           U32 *wasted) { 
     748    U32 *wasted) { 
    751749  U32 _files = 0, _used = 0, _free_pages = 0, _wasted = 0; 
    752750  U32 i; 
     
    840838 * is. 
    841839 */ 
    842 fs_err_t nx_fs_defrag_simple(void) { 
    843   U32 i = FS_PAGE_START; 
     840fs_err_t nx_fs_defrag_simple_zone(U32 zone_start, U32 zone_end) { 
    844841  U32 next_hole, next_file, first_next_file, hole_length = 0, end_of_block; 
    845842  U32 best_block_origin =0, best_block_size=0, block_size = 0; 
     843  U32 i; 
    846844  fs_err_t err = FS_ERR_NO_ERROR; 
    847845 
    848   while (i < FS_PAGE_END) { 
     846  NX_ASSERT(zone_start >= FS_PAGE_START); 
     847  NX_ASSERT(zone_end <= FS_PAGE_END); 
     848  NX_ASSERT(zone_start <= zone_end); 
     849 
     850  i = zone_start; 
     851  nx_display_string("<<  "); 
     852  nx_display_uint(i); 
     853  nx_display_end_line(); 
     854 
     855  while (i < zone_end) { 
    849856    /* Find the next hole, and its size. */ 
    850  
    851857    err = nx_fs_find_next_hole(i, &next_hole); 
    852858    if (err != FS_ERR_NO_ERROR) { 
     
    880886 
    881887      if (block_size != hole_length && 
    882         nx_fs_find_next_origin(end_of_block, &next_file) != FS_ERR_NO_ERROR) { 
     888          nx_fs_find_next_origin(end_of_block, &next_file) != FS_ERR_NO_ERROR) { 
    883889        break; 
    884890      } 
    885     } while (next_file < FS_PAGE_END && block_size != hole_length); 
     891    } while (next_file < zone_end && block_size != hole_length); 
    886892 
    887893    /* Move the block to fill the hole and move the search start 
     
    901907    /* Else, if a best match has been found, move it. */ 
    902908    else if (best_block_origin != 0) { 
     909      nx_display_string("bmatch\n"); 
     910      nx_display_uint(best_block_origin); 
     911      nx_display_string(">"); 
     912      nx_display_uint(next_hole); 
     913      nx_display_string(" "); 
     914      nx_display_uint(best_block_size); 
     915      nx_display_end_line(); 
     916 
    903917      err = nx_fs_move_region(best_block_origin, next_hole, best_block_size); 
    904918      if (err != FS_ERR_NO_ERROR) { 
     
    907921 
    908922      i = next_hole + best_block_size; 
     923      nx_display_string("after "); 
     924      nx_display_uint(i); 
     925      nx_display_end_line(); 
     926      return FS_ERR_NO_ERROR; 
    909927    } 
    910928 
     
    915933      err = nx_fs_find_next_hole(first_next_file, &end_of_block); 
    916934      if (err != FS_ERR_NO_ERROR) { 
    917         end_of_block = FS_PAGE_END; 
    918       } 
     935        end_of_block = zone_end; 
     936      } 
     937 
     938      nx_display_string("pull\n"); 
    919939 
    920940      err = nx_fs_move_region(first_next_file, next_hole, 
     
    931951} 
    932952 
     953/* Simple defragmentation of the whole flash. */ 
     954inline fs_err_t nx_fs_defrag_simple(void) { 
     955  return nx_fs_defrag_simple_zone(FS_PAGE_START, FS_PAGE_END); 
     956} 
     957 
    933958fs_err_t nx_fs_defrag_for_file_by_name(char *name) { 
    934959  U32 origin; 
     
    940965  } 
    941966 
    942   /* Fall back to simple defrag. */ 
    943   return nx_fs_defrag_simple(); 
     967  return FS_ERR_FILE_NOT_FOUND; 
     968} 
     969 
     970static fs_err_t nx_fs_swap_regions(U32 start1, U32 dest1, U32 len1, 
     971                                   U32 start2, U32 len2) { 
     972  U32 data[EFC_PAGE_WORDS] = {0}; 
     973  fs_err_t err; 
     974  U32 i, j; 
     975 
     976  NX_ASSERT(len2 <= len1); 
     977 
     978  nx_display_string("swap\n"); 
     979  nx_display_uint(start1); 
     980  nx_display_string("-"); 
     981  nx_display_uint(dest1); 
     982  nx_display_string("-"); 
     983  nx_display_uint(len1); 
     984  nx_display_end_line(); 
     985 
     986  nx_display_uint(start2); 
     987  nx_display_string("-"); 
     988  nx_display_uint(len2); 
     989  nx_display_end_line(); 
     990 
     991  for (i=0, j=0; i<len1; i++, j++) { 
     992    if (j < len2) { 
     993      nx__efc_read_page(start2 + j, data); 
     994      nx__efc_erase_page(start2 + j, 0); 
     995    } 
     996 
     997    err = nx_fs_move_region(start1 + i, dest1 + i, 1); 
     998    if (err != FS_ERR_NO_ERROR) { 
     999      return err; 
     1000    } 
     1001 
     1002    if (j < len2 && !nx__efc_write_page(data, start1 + j)) { 
     1003      return FS_ERR_FLASH_ERROR; 
     1004    } 
     1005  } 
     1006 
     1007  return FS_ERR_NO_ERROR; 
    9441008} 
    9451009 
    9461010fs_err_t nx_fs_defrag_for_file_by_origin(U32 origin) { 
    947   nx_fs_move_region(origin, 1, 1); // TBR 
    948  
    949   return FS_ERR_NO_ERROR; 
     1011  U32 next_origin, next_hole, last_origin, last_npages, npages; 
     1012  volatile U32 *metadata; 
     1013  fs_err_t err; 
     1014 
     1015  /* First, trivial case: the file is already at the end of the flash. 
     1016   * If it still has free space after him, job's done. Otherwise, launch 
     1017   * a defrag simple. 
     1018   */ 
     1019  err = nx_fs_find_last_origin(&last_origin); 
     1020  if (err != FS_ERR_NO_ERROR) { 
     1021    return err; 
     1022  } 
     1023 
     1024  metadata = &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]); 
     1025  npages = nx_fs_get_file_page_count( 
     1026    nx_fs_get_file_size_from_metadata(metadata)); 
     1027 
     1028  metadata = &(FLASH_BASE_PTR[last_origin*EFC_PAGE_WORDS]); 
     1029  last_npages = nx_fs_get_file_page_count( 
     1030    nx_fs_get_file_size_from_metadata(metadata)); 
     1031 
     1032  if (origin == last_origin) { 
     1033    nx_display_string("case1\n"); 
     1034    return nx_fs_defrag_simple(); 
     1035  } 
     1036 
     1037  /* Second case: we can move our file to the end of the flash. If this 
     1038   * is possible, move the file and call nx_fs_defrag_simple(). 
     1039   */ 
     1040  if (FS_PAGE_END - (last_origin + last_npages) > npages) { 
     1041    nx_display_string("case2\n"); 
     1042 
     1043    err = nx_fs_move_region(origin, last_origin + last_npages, npages); 
     1044    if (err != FS_ERR_NO_ERROR) { 
     1045      return err; 
     1046    } 
     1047 
     1048    return nx_fs_defrag_simple(); 
     1049  } 
     1050 
     1051  /* Third case, trickier: if we can *swap* the file with the last one 
     1052   * of the flash, do it and we're back into case 2). 
     1053   */ 
     1054  do { 
     1055    if (nx_fs_find_next_hole(origin, &next_hole) != FS_ERR_NO_ERROR) { 
     1056      break; 
     1057    } 
     1058 
     1059    if (nx_fs_find_next_origin(next_hole, &next_origin) != 
     1060      FS_ERR_NO_ERROR) { 
     1061      break; 
     1062    } 
     1063  } while (next_origin != last_origin); 
     1064 
     1065  if (next_origin == last_origin && npages <= FS_PAGE_END - next_hole && 
     1066    last_npages <= npages) { 
     1067    nx_display_string("case3\n"); 
     1068 
     1069    /* Swap our file with the last one, if they fit. */ 
     1070    err = nx_fs_swap_regions(origin, next_hole, npages, 
     1071                             last_origin, last_npages); 
     1072    if (err != FS_ERR_NO_ERROR) { 
     1073      return err; 
     1074    } 
     1075 
     1076    return nx_fs_defrag_simple(); 
     1077  } 
     1078 
     1079  return FS_ERR_NO_SPACE_LEFT_ON_DEVICE; 
    9501080} 
    9511081 
     
    10151145 
    10161146      hole_size = next_origin - (i + npages); 
    1017  
    1018       nx_display_uint(i); 
    1019       nx_display_string(" "); 
    1020       nx_display_uint(npages); 
    1021       nx_display_string(" "); 
    1022       nx_display_uint(hole_size); 
    1023       nx_display_string(">"); 
    1024  
    10251147      i += npages + mean_space_per_file; 
    1026       nx_display_uint(i); 
    1027       nx_display_end_line(); 
    10281148 
    10291149      /* First, trivial case: the hole size equals mean_space_per_file. 
  • nxos/base/lib/fs/fs.h

    r612 r616  
    210210void nx_fs_dump(void); 
    211211 
     212/** Perform a simple defragmentation of the flash filesystem on the 
     213 * given zone of the flash. 
     214 * 
     215 * @param zone_start Beginning of the zone to defragment. 
     216 * @param zone_end End of the zone. 
     217 * @return A @a fs_err_t describing the outcome of the operation. 
     218 */ 
     219fs_err_t nx_fs_defrag_simple_zone(U32 zone_start, U32 zone_end); 
     220 
    212221/** Perform a simple defragmentation of the flash filesystem. 
    213222 * 
     
    218227 * @return A @a fs_err_t describing the outcome of the operation. 
    219228 */ 
    220 fs_err_t nx_fs_defrag_simple(void); 
     229inline fs_err_t nx_fs_defrag_simple(void); 
    221230 
    222231/** Perform a simple, file oriented defragmentation of the flash. 
  • nxos/systems/tests/fs.c

    r615 r616  
    77 */ 
    88 
     9#include "base/types.h" 
     10#include "base/at91sam7s256.h" 
    911#include "base/display.h" 
    1012#include "base/util.h" 
     
    148150} 
    149151 
     152void fs_test_defrag_for_file(void) { 
     153  U32 metadata[4*EFC_PAGE_WORDS] = {0}; 
     154  union U32tochar nameconv; 
     155 
     156  setup(); 
     157 
     158  metadata[0] = (0x42 << 24); 
     159  memcpy(nameconv.chars, (void *)"test42", 6); 
     160  memcpy(metadata+2, nameconv.integers, 32); 
     161 
     162  nx_display_string("Starting...\n"); 
     163 
     164  spawn_file("test1", 3000); 
     165  //spawn_file("test2", 30000); 
     166  //spawn_file("test3", 3000); 
     167  //remove_file("test2"); 
     168  nx__efc_write_page(metadata, 1020); 
     169 
     170  nx_fs_dump(); 
     171  while (nx_avr_get_button() != BUTTON_OK); 
     172  nx_systick_wait_ms(500); 
     173 
     174  nx_display_clear(); 
     175  nx_display_string("Defrag: "); 
     176  nx_display_uint(nx_fs_defrag_for_file_by_name("test1")); 
     177  nx_display_string(" done.\n"); 
     178  while (nx_avr_get_button() != BUTTON_OK); 
     179  nx_systick_wait_ms(500); 
     180 
     181  nx_display_clear(); 
     182  nx_fs_dump(); 
     183  while (nx_avr_get_button() != BUTTON_OK); 
     184  nx_systick_wait_ms(500); 
     185 
     186  destroy(); 
     187} 
     188 
    150189void fs_test_defrag_best_overall(void) { 
    151   U32 data[256] = {0}; 
    152   union U32tochar nameconv; 
    153  
    154   setup(); 
    155  
    156   nx_display_string("Starting...\n"); 
    157  
    158   data[0] = (0x42 << 24); 
    159   memcpy(nameconv.chars, (void *)"test42", 6); 
    160   memcpy(data+2, nameconv.integers, 32); 
    161  
    162   spawn_file("test1", 300); 
    163   spawn_file("test2", 300); 
    164   spawn_file("test3", 102360); 
    165   spawn_file("test4", 30); 
    166   spawn_file("test5", 102560); 
     190  setup(); 
     191 
     192  nx_display_string("Starting...\n"); 
     193 
     194  spawn_file("test1", 106968); 
     195  spawn_file("test2", 12750); 
     196  spawn_file("test3", 106968); 
    167197  remove_file("test2"); 
    168   remove_file("test4"); 
    169198 
    170199  nx_fs_dump(); 
  • nxos/systems/tests/fs.h

    r612 r616  
    1414void fs_test_defrag_empty(void); 
    1515void fs_test_defrag_simple(void); 
     16void fs_test_defrag_for_file(void); 
    1617void fs_test_defrag_best_overall(void); 
    1718 
  • nxos/systems/tests/tests.c

    r612 r616  
    869869  //fs_test_defrag_simple(); 
    870870  //fs_test_defrag_empty(); 
    871   fs_test_defrag_best_overall(); 
     871  fs_test_defrag_for_file(); 
     872  //fs_test_defrag_best_overall(); 
    872873  goodbye(); 
    873874}