<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux內(nèi)核中的文件描述符(六)--fd的分配--expand_files

          linux內(nèi)核中的文件描述符(六)--fd的分配--expand_files

          作者: 時(shí)間:2016-11-22 來(lái)源:網(wǎng)絡(luò) 收藏
          Kernel version:2.6.14

          CPU architecture:ARM920T

          本文引用地址:http://www.ex-cimer.com/article/201611/320002.htm

          Author:ce123(http://blog.csdn.net/ce123)

          我們先貼出expand_files函數(shù)的源碼:

          [plain]view plaincopy
          print?
          1. intexpand_files(structfiles_struct*files,intnr)
          2. {
          3. interr,expand=0;
          4. structfdtable*fdt;
          5. fdt=files_fdtable(files);
          6. if(nr>=fdt->max_fdset||nr>=fdt->max_fds){//我們?cè)谇懊娴奈恼轮幸呀?jīng)分析過(guò),初始時(shí)max_fdset=1024,max_fds=32
          7. if(fdt->max_fdset>=NR_OPEN||//#defineNR_OPEN(1024*1024)/*Absoluteupperlimitonfdnum*/
          8. fdt->max_fds>=NR_OPEN||nr>=NR_OPEN){
          9. err=-EMFILE;//max_fdset和max_fds都不能大于NR_OPEN,否則返回-EMFILE,即打開(kāi)太多的文件
          10. gotoout;
          11. }
          12. expand=1;
          13. if((err=expand_fdtable(files,nr)))//真正進(jìn)行擴(kuò)展
          14. gotoout;
          15. }
          16. err=expand;
          17. out:
          18. returnerr;
          19. }

          expand_files函數(shù)進(jìn)行一些檢查后調(diào)用expand_fdtable進(jìn)行文件描述符表的擴(kuò)展,下面分析expand_fdtable函數(shù)。

          [plain]view plaincopy
          print?
          1. staticintexpand_fdtable(structfiles_struct*files,intnr)
          2. __releases(files->file_lock)
          3. __acquires(files->file_lock)
          4. {
          5. interror=0;
          6. structfdtable*fdt;
          7. structfdtable*nfdt=NULL;
          8. spin_unlock(&files->file_lock);
          9. nfdt=alloc_fdtable(nr);//根據(jù)nr重新創(chuàng)建一個(gè)新的fdtable
          10. if(!nfdt){
          11. error=-ENOMEM;
          12. spin_lock(&files->file_lock);
          13. gotoout;
          14. }
          15. spin_lock(&files->file_lock);
          16. fdt=files_fdtable(files);
          17. /*
          18. *Checkagainsinceanothertaskmayhaveexpandedthe
          19. *fdtablewhilewedroppedthelock
          20. */
          21. if(nr>=fdt->max_fds||nr>=fdt->max_fdset){//nr值必須大于max_fds和max_fdset值,這里再次進(jìn)行檢查是防止另一個(gè)進(jìn)程進(jìn)行了expand
          22. copy_fdtable(nfdt,fdt);//將舊的fdtable中的內(nèi)容拷貝至新的fdtable
          23. }else{
          24. /*Somebodyexpandedwhilewedroppedfile_lock*/
          25. spin_unlock(&files->file_lock);
          26. __free_fdtable(nfdt);
          27. spin_lock(&files->file_lock);
          28. gotoout;
          29. }
          30. rcu_assign_pointer(files->fdt,nfdt);//用新的fdtable替換舊的fdtable
          31. free_fdtable(fdt);//釋放舊的fdtable
          32. out:
          33. returnerror;
          34. }
          我們?cè)賮?lái)看一下擴(kuò)展文件描述符表的關(guān)鍵函數(shù)alloc_fdtable,其定義如下:

          [plain]view plaincopy
          print?
          1. staticstructfdtable*alloc_fdtable(intnr)
          2. {
          3. structfdtable*fdt=NULL;
          4. intnfds=0;
          5. fd_set*new_openset=NULL,*new_execset=NULL;
          6. structfile**new_fds;
          7. fdt=kmalloc(sizeof(*fdt),GFP_KERNEL);
          8. if(!fdt)
          9. gotoout;
          10. memset(fdt,0,sizeof(*fdt));
          11. nfds=__FD_SETSIZE;//#define__FD_SETSIZE1024
          12.     //#definePAGE_SHIFT12
          13.     //#definePAGE_SIZE(1UL<
          14. /*Expandtothemaxineasysteps*/
          15. do{
          16. if(nfds<(PAGE_SIZE*8))//dfds=1024
          17. nfds=PAGE_SIZE*8;
          18. else{
          19. nfds=nfds*2;
          20. if(nfds>NR_OPEN)
          21. nfds=NR_OPEN;
          22. }
          23. }while(nfds<=nr);//第一次expand時(shí),nr應(yīng)該等于32
          24. new_openset=alloc_fdset(nfds);//分配打開(kāi)文件位圖
          25. new_execset=alloc_fdset(nfds);
          26. if(!new_openset||!new_execset)
          27. gotoout;
          28. fdt->open_fds=new_openset;
          29. fdt->close_on_exec=new_execset;
          30. fdt->max_fdset=nfds;//更新max_fdset值,此時(shí)這個(gè)值為32k
          31. nfds=NR_OPEN_DEFAULT;//nfds=32
          32. /*
          33. *Expandtothemaxineasysteps,andkeepexpandingituntil
          34. *wehaveenoughfortherequestedfdarraysize.
          35. */
          36. do{
          37. #ifNR_OPEN_DEFAULT<256
          38. if(nfds<256)
          39. nfds=256;//nfds=256(32->256->1024)
          40. //無(wú)法超過(guò)1024,因?yàn)樵谧铋_(kāi)始的就進(jìn)行了檢查,一定要小于current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
          41. else
          42. #endif
          43. if(nfds<(PAGE_SIZE/sizeof(structfile*)))
          44. nfds=PAGE_SIZE/sizeof(structfile*);
          45. else{
          46. nfds=nfds*2;
          47. if(nfds>NR_OPEN)
          48. nfds=NR_OPEN;
          49. }
          50. }while(nfds<=nr);
          51. new_fds=alloc_fd_array(nfds);//分配文件描述符數(shù)組
          52. if(!new_fds)
          53. gotoout;
          54. fdt->fd=new_fds;
          55. fdt->max_fds=nfds;//更新max_fds
          56. fdt->free_files=NULL;
          57. returnfdt;
          58. out:
          59. if(new_openset)
          60. free_fdset(new_openset,nfds);
          61. if(new_execset)
          62. free_fdset(new_execset,nfds);
          63. kfree(fdt);
          64. returnNULL;
          65. }
          alloc_fd_array和alloc_fdset采用kmalloc或者vmalloc進(jìn)行內(nèi)存分配。


          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();