a new version + a bunch of crap (temp)

This commit is contained in:
2026-02-03 17:15:04 +01:00
parent 92c2963dd6
commit 0dbeb6af86
8 changed files with 2536 additions and 0 deletions

726
page.c.ccomp Normal file
View File

@@ -0,0 +1,726 @@
CCC@ sh_uint64SH_STATUS_INVALID_PARAMETERreturn SH_PAGE_SIZEsh_page_VIRTUAL_ADRESSphysical_memory_pages_countSH_STATUS_INVALID_INTERNAL_PASH_STATUS_SUCCESSsh_log_send_stringSH_STATUS_OUT_OF_MEMORYSH_LOG_SOURCE_PAGEstatussh_page_PAGE_TABLE_POOLsh_page_PHYSICAL_ADRESSSH_PAGE_PRESENT
size_bytessh_page_ptp_pa_to_va SH_STATUSmemory_map_cursorSH_STATUS_ERROR_VA_NOT_MAPPEDcurrent_free_blockcurrent_used_blocksh_page_MEMORY_MAP_HEADER pages_neededphysical_bitmap_size_bytessh_page_set_pages_range_bitmap
SH_NULLPTRmemory_map_buffermemory_map_headerSH_STATUS_VA_NOT_MAPPEDphysical_bitmapphysical_bitmap_size_pagessh_log_send_uintnsh_log_send_uintn_hexlargest_free_blocklargest_used_blockptp
page_indexpage_table_pool mem_stats&sh_page_map_contiguous_pages_range_ptpphysical_memory_bytes_count sh_log_errorsh_uint8!sh_page_search_available_va_range
page_countva_range_size_bytesSH_PAGE_MAX_PAGES_COUNTsh_page_is_va_range_mapped_ptp+sh_page_search_physical_contiguous_block_naSH_STATUS_VA_PARTIALLY_MAPPEDpage_table_pool_va_ptr
contiguousfree_blocks_countused_blocks_countelseSH_PAGE_CONVENTIONAL_MEMORY candidate_pa candidate_vaptp_alloc_bitmapsh_page_ptp_alloc_one_page
sh_log_ldebugxFFFULLcandidate_start®../include/page.h"
­std.h>
__attribute__((section(".bss")))
Ÿ ë Û[64*1024];
Ÿ ë *Þ;
__attribute__((section(".bss")))
Ÿ À Å=0;
__attribute__((section(".bss")))
Ÿ À é=0;
__attribute__((section(".bss")))
Ÿ À Ø=0;
__attribute__((section(".bss")))
Ÿ À ß=0;
Ÿ Ä ó=SH_PAGE_NULL_VA;
Ñ sh_page_load_boot_ä_va(Ä pt_pool_va) {
ó=pt_pool_va;
ý("Page table pool VA: 0x",Ê);
á((À)ó);
È("\n");
ë first_byte=*(ë*)(ó);
sh_log_debug("If you can see this message, no fault happened.",Ê);
 Ç;
}
Ä sh_page_get_boot_ä_va() {
 ó;
}
Ñ sh_page_copy_memory_map() {
 sh_mem_copy(Û,(ª*)SH_PAGE_MEMORY_MAP_VA,ž(Û));
}
Ñ sh_page_check_memory_map() {
Ÿ ‡ ë memory_map_sig[8]={'S','h','e','M','m','a','p','B'};
” (sh_mem_compare(memory_map_sig,Û,ž(memory_map_sig))==Ñ_MEM_NOT_EQUAL) {
sh_log_critical("Memory map esn't have signature on.",Ê);
 Ñ_INVALID_SIGNATURE;
}
Ö *Ü=(Ö *)Û;
ý("Memory map entry count: ",Ê);
à((À)Ü->entry_count);
È("\n");
ý("Memory map entry size: ",Ê);
à((À)Ü->entry_size);
È("\n");
ý("Memory map syntax version: ",Ê);
à((À)Ü->mmap_syntax_version);
È("\n");
” (Ü->entry_count*Ü->entry_size+ž(Ö)>ž(Û)) {
ê("Memory map overflow allocated buffer.",Ê);
 Ñ_MMAP_BUFFER_OVERFLOW;
}
 Ç;
}
ª sh_page_dump_memory_map() {
Ö *Ü=(Ö *)Û;
È("Memory map dump:\n");
È("Header:\n");
(À i=0;i<ž(Ö);++i) {
à((À)Û[i]);
È(" ");
}
È("\n");
(À i=0;i<Ü->entry_count;++i) {
È("Entry number ");
à(i);
È(" : ");
(À y=0;y<ž(sh_page_MEMORY_MAP_ENTRY);++y) {
à((À)Û[ž(Ö)+i*ž(sh_page_MEMORY_MAP_ENTRY)+y]);
È(" ");
}
È("\n");
}
}
À sh_page_get_physical_memory_amount_pages() {
 Å;
}
À sh_page_get_physical_memory_amount_bytes() {
 é;
}
À sh_page_get_one_page_na() {
À í=Å;
À bitmap_word_count=(í+63)/64;
(À word=0;word<bitmap_word_count;word++) {
À value=Þ[word];
” (value==0xFFFFFFFFFFFFFFFFULL) {
‰;
}
(À bit=0;bit<64;bit++) {
À å=(word*64)+bit;
” (å>=í) {
 0;
}
” ((value & (1ULL<<bit))==0) {
 å*Ã;
}
}
}
 0;
}
Ñ Ù(ë *bitmap,À í_in_bitmap,À å,À í,sh_ƒ state) {
” (bitmap==Ú) {
 Á;
}
” (å+í>í_in_bitmap) {
 Á;
}
(À i=0;i<í;++i) {
À page=å+i;
À byte_index=page/8;
ë bit_index=page%8;
” (state) {
bitmap[byte_index]|=(ë)(1u<<bit_index);
} ÷ {
bitmap[byte_index]&=(ë)~(1u<<bit_index);
}
}
 Ç;
}
Ñ sh_page_init_ä(Í ä_pa,Ä ä_va,À initial_fill_level,Ì *æ) {
æ->page_table_pa=ä_pa;
æ->page_table_va=ä_va;
æ->ä_pages_count=SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT;
æ->û_u64_count=SH_PAGE_PTP_ALLOCATOR_BITMAP_UINT64;
Ñ Ë=sh_mem_set_8((ë*)æ->û,SH_FALSE,ž(æ->û));
” (sh_Ë_error(Ë)) {
ê("Error: couldn't initialize page table pool bitmap.",Ê);
 Ñ_PT_POOL_NO_BITMAP_INIT;
}
” (initial_fill_level!=0) {
Ë=Ù((ë*)æ->û,æ->ä_pages_count,0,initial_fill_level,SH_TRUE);
” (sh_Ë_error(Ë)) {
ê("Error: couldn't initialize pages tables already alocated.",Ê);
 Ñ_PT_POOL_NO_PAGE_SET;
}
}
 Ç;
}
Ñ sh_page_dump_ä_bitmap(Ì *ä) {
(À i=0;i<ä->û_u64_count;++i) {
È(" 0x");
á(ä->û[i]);
}
È("\n");
 Ç;
}
Í ü(Ì *pt_pool) {
” (pt_pool==Ú) {
 Á;
}
À í=pt_pool->ä_pages_count;
À bitmap_word_count=(í+63)/64;
(À word=0;word<bitmap_word_count;word++) {
À value=pt_pool->û[word];
” (value==0xFFFFFFFFFFFFFFFFULL) {
‰;
}
(À bit=0;bit<64;bit++) {
À å=(word*64)+bit;
” (å>=í) {
 0;
}
” ((value & (1ULL<<bit))==0) {
pt_pool->û[word]|=(1ULL<<bit);
Í pa=pt_pool->page_table_pa+å*Ã;
 pa;
}
}
}
 0;
}
Ñ sh_page_map_one_page_ä(Ì *ä,Ä va,Í pa,À flags) {
” (ä==Ú) Â Á;
” (va%Ã!=0 || pa%Ã!=0) Â Á;
À pml4_i=(va>>39) & 0x1FF;
À pdpt_i=(va>>30) & 0x1FF;
À pd_i=(va>>21) & 0x1FF;
À pt_i=(va>>12) & 0x1FF;
À *pdpt;
À *pd;
À *pt;
À *pml4=(À*)ä->page_table_va;
” (!(pml4[pml4_i] & Î)) {
Í pdpt_pa=ü(ä);
” (!pdpt_pa) Â É;
pdpt=Ð(ä,pdpt_pa);
” (!pdpt) Â Æ;
sh_mem_set_8((ë*)pdpt,0,Ã);
pml4[pml4_i]=pdpt_pa | SH_PAGE_TABLE_FLAGS | Î;
} ÷ {
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
” (!pdpt) Â Æ;
}
” (!(pdpt[pdpt_i] & Î)) {
Í pd_pa=ü(ä);
” (!pd_pa) Â É;
pd=Ð(ä,pd_pa);
” (!pd) Â Æ;
sh_mem_set_8((ë*)pd,0,Ã);
pdpt[pdpt_i]=pd_pa | SH_PAGE_TABLE_FLAGS | Î;
} ÷ {
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
” (!pd) Â Æ;
}
” (!(pd[pd_i] & Î)) {
Í pt_pa=ü(ä);
” (!pt_pa) Â É;
pt=Ð(ä,pt_pa);
” (!pt) Â Æ;
sh_mem_set_8((ë*)pt,0,Ã);
pd[pd_i]=pt_pa | SH_PAGE_TABLE_FLAGS | Î;
} ÷ {
pt=Ð(ä,pd[pd_i] & ~0þ);
” (!pt) Â Æ;
}
pt[pt_i]=(pa & ~0þ) | flags | Î;
 Ç;
}
Ñ sh_page_is_va_mapped_ä(Ì *ä,Ä va) {
” (ä==Ú) Â Á;
À pml4_i=(va>>39) & 0x1FF;
À pdpt_i=(va>>30) & 0x1FF;
À pd_i=(va>>21) & 0x1FF;
À pt_i=(va>>12) & 0x1FF;
À *pdpt;
À *pd;
À *pt;
À *pml4=(À*)ä->page_table_va;
” (!(pml4[pml4_i] & Î)) {
 Ý;
} ÷ {
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
” (pdpt==0) Â Æ;
}
” (!(pdpt[pdpt_i] & Î)) {
 Ý;
} ÷ {
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
” (pd==0) Â Æ;
}
” (!(pd[pd_i] & Î)) {
 Ý;
} ÷ {
pt=Ð(ä,(pd[pd_i] & ~0þ));
” (pt==0) Â Æ;
}
” (!(pt[pt_i] & Î)) {
 Ý;
} ÷ {
 Ñ_VA_MAPPED;
}
}
Ñ ð(Ì *ä,Ä va,À Ï) {
” (ä==Ú) Â Á;
” (va%Ã!=0 || Ï%Ã!=0 || Ï==0) Â Á;
À counter=0;
(À i=0;i<Ï/Ã;i++) {
” (sh_page_is_va_mapped_ä(ä,va+i*Ã)==Ñ_VA_MAPPED) {
counter++;
}
}
” (counter==0) Â Ý;
” (counter==Ï/Ã) Â Ñ_VA_FULLY_MAPPED;
 ò;
}
Ñ ì(Ì *ä,Ä range_base,Ä range_Ï,À Ï,Ä *adress_found) {
” (ä==Ú || adress_found==Ú) {
È("1\n");
 Á;
}
” (Ï==0 || Ï%Ã!=0) {
È("2\n");
 Á;
};
” (range_base%Ã!=0 || range_Ï%4096!=0 || range_Ï==0) {
È("3\n");
 Á;
};
À ×=Ï/Ã;
Ä current_va=range_base;
À ô=0;
Ä ÿ=0;
¬ (current_va<range_base+range_Ï) {
Ñ Ë=sh_page_is_va_mapped_ä(ä,current_va);
” (Ë==Ý) {
” (ô==0) {
ÿ=current_va;
}
ô++;
” (ô==×) {
*adress_found=(Ä)ÿ;
 Ç;
}
} ÷ ” (Ë==Ñ_VA_MAPPED) {
ô=0;
} ÷ {
 Æ;
}
current_va+=Ã;
}
 É;
}
Ñ è(Ì *ä,Ä va,Í pa,À flags,À Ï) {
” (ä==Ú) Â Á;
” (va%Ã!=0 || pa%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
” ((flags & SH_PAGE_PS)==SH_PAGE_PS) Â Á;
À pages=Ï/Ã;
Ñ Ë=ð(ä,va,Ï);
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
” (Ë==Ñ_VA_FULLY_MAPPED) Â Ñ_ERROR_VA_FULLY_MAPPED;
(À i=0;i<pages;i++) {
Ë=sh_page_map_one_page_ä(ä,va+i*Ã,pa+i*Ã,flags);
” (Ë!=Ç) {
 Ë;
}
}
 Ç;
}
Ñ ñ(À ×,Í *pa) {
” (×==0) Â Á;
À í=sh_page_get_physical_memory_amount_pages();
À ô=0;
À ÿ=0;
(À å=0;å<í;å++) {
” (!sh_page_is_allocated(Þ,å)) {
” (ô==0) ÿ=å;
ô++;
” (ô==×) {
*pa=ÿ*Ã;
 Ç;
}
} ÷ {
ô=0;
}
}
 É;
}
Ñ sh_page_alloc_ô(Ì *ä,À Ï,Ä *va) {
” (ä==Ú || va==Ú || Ï==0) Â Á;
À ×=Ï/Ã;
” (Ï%Ã!=0) ×++;
Ä ú=0;
Ñ Ë=ì(ä,0x0,0x00007FFFFFFFF000,×*Ã,&ú);
” (Ë==É) {
 É;
} ÷ ” (Ë==Æ) {
 Ñ_KERNEL_PANIC;
} ÷ ” (Ë==Á) {
 É;
} ÷ ” (sh_Ë_error(Ë)) {
 É;
}
Í ù=0;
Ë=ñ(×,&ù);
” (Ë!=Ç) {
 É;
}
Ë=è(ä,ú,ù,Î | SH_PAGE_NX | SH_PAGE_RW,×*Ã);
” (Ë!=Ç) Â Ë;
Ù(Þ,Å,(À)ù/Ã,×,SH_TRUE);
*va=ú;
 Ç;
}
Ñ sh_page_alloc_ô_extended(Ì *ä,À Ï,Ä* va,DEFAULT À flags,DEFAULT Ä va_range_start,DEFAULT À î) {
” (ä==Ú || va==Ú || Ï==0) Â Á;
” (flags==SH_DEFVALUE) flags=Î | SH_PAGE_NX | SH_PAGE_RW;
” (va_range_start==SH_DEFVALUE) va_range_start=0x0;
” (î==SH_DEFVALUE) î=0x00007FFFFFFFF000;
” (va_range_start%Ã!=0 || î==0 || î%Ã!=0) Â Á;
À ×=Ï/Ã;
” (Ï%Ã!=0) ×++;
Ä ú=0;
Ñ Ë=ì(ä,va_range_start,î,×*Ã,&ú);
” (Ë==É) {
 É;
} ÷ ” (Ë==Æ) {
 Ñ_KERNEL_PANIC;
} ÷ ” (Ë==Á) {
 É;
} ÷ ” (sh_Ë_error(Ë)) {
 É;
}
Í ù=0;
Ë=ñ(×,&ù);
” (Ë!=Ç) {
 É;
}
Ë=è(ä,ú,ù,flags,×*Ã);
” (Ë!=Ç) Â Ë;
Ù(Þ,Å,(À)ù/Ã,×,SH_TRUE);
*va=ú;
 Ç;
}
Ñ sh_page_unmap_one_page_ä(Ì *ä,Ä va) {
” (ä==Ú) Â Á;
” (va%Ã!=0) Â Á;
À pml4_i=(va>>39) & 0x1FF;
À pdpt_i=(va>>30) & 0x1FF;
À pd_i=(va>>21) & 0x1FF;
À pt_i=(va>>12) & 0x1FF;
À *pdpt;
À *pd;
À *pt;
À *pml4=(À*)ä->page_table_va;
” (!(pml4[pml4_i] & Î)) {
 Ó;
} ÷ {
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
” (!pdpt) Â Æ;
}
” (!(pdpt[pdpt_i] & Î)) {
 Ó;
} ÷ {
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
” (!pd) Â Æ;
}
” (!(pd[pd_i] & Î)) {
 Ó;
} ÷ {
pt=Ð(ä,pd[pd_i] & ~0þ);
” (!pt) Â Æ;
}
pt[pt_i]=0x0ULL;
__asm__ «("invlpg (%0)" :: "r"(va) : "memory");
 Ç;
}
Ñ sh_page_unmap_ô_pages_range_ä(Ì *ä,Ä va,À Ï) {
” (ä==Ú) Â Á;
” (va%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
À pages=Ï/Ã;
Ñ Ë=ð(ä,va,Ï);
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
” (Ë==Ý) Â Ó;
(À i=0;i<pages;i++) {
Ë=sh_page_unmap_one_page_ä(ä,va+i*Ã);
” (Ë!=Ç) {
 Ë;
}
}
 Ç;
}
Ñ sh_page_ä_va_to_pa(Ì *ä,Ä va,Í *pa) {
” (ä==Ú || pa==Ú) Â Á;
” (va%Ã!=0) Â Á;
À pml4_i=(va>>39) & 0x1FF;
À pdpt_i=(va>>30) & 0x1FF;
À pd_i=(va>>21) & 0x1FF;
À pt_i=(va>>12) & 0x1FF;
À *pdpt;
À *pd;
À *pt;
À *pml4=(À*)ä->page_table_va;
” (!(pml4[pml4_i] & Î)) {
 Ó;
} ÷ {
pdpt=Ð(ä,(pml4[pml4_i] & ~0þ));
” (!pdpt) Â Æ;
}
” (!(pdpt[pdpt_i] & Î)) {
 Ó;
} ÷ {
pd=Ð(ä,(pdpt[pdpt_i] & ~0þ));
” (!pd) Â Æ;
}
” (!(pd[pd_i] & Î)) {
 Ó;
} ÷ {
pt=Ð(ä,pd[pd_i] & ~0þ);
” (!pt) Â Æ;
}
” (!(pt[pt_i] & Î)) Â Ó;
*pa=pt[pt_i] & 0x000FFFFFFFFFF000;
 Ç;
}
Ñ sh_page_unalloc_one_page(Ì *ä,Ä va) {
” (ä==Ú) Â Á;
” (va%Ã!=0) Â Á;
Í equivalent_pa;
Ñ Ë=sh_page_ä_va_to_pa(ä,va,&equivalent_pa);
” (Ë!=Ç) Â Ë;
Ë=sh_page_unmap_one_page_ä(ä,va); // If this call  Ó, there is a severe bug that should cause kernel panic because sh_page_ä_va_to_pa should already have Âed exact same error code.
” (Ë!=Ç) Â Ë;
Ë=Ù(Þ,Å,(À)(equivalent_pa/Ã),1,SH_FALSE);
” (Ë!=Ç) Â Ë;
 Ç;
}
Ñ sh_page_unalloc_ô(Ì *ä,Ä va,À Ï) {
” (ä==Ú) Â Á;
” (va%Ã!=0 || Ï==0 || Ï%Ã!=0) Â Á;
Ñ Ë=ð(ä,va,Ï);
” (Ë==Ý) Â Ó;
” (Ë==ò) Â Ñ_ERROR_VA_PARTIALLY_MAPPED;
À pages=Ï/Ã;
(À i=0;i<pages;i++) {
Ë=sh_page_unalloc_one_page(ä,va+i*Ã);
” (Ë!=Ç) {
 Ë;
}
}
 Ç;
}
Ñ sh_page_analyse_memory_map(Ì *ä) {
” (ä==Ú) Â Á;
Ö *Ü=(Ö *)Û;
sh_page_MEMORY_MAP_ENTRY *Ò=(sh_page_MEMORY_MAP_ENTRY *)(Û+ž(Ö));
sh_ƒ verbose=sh_log_get_log_level()==0;
sh_ƒ log=sh_log_get_log_level()<=1;
À highest_usable_segment=0;
À highest_usable_page=0;
À biggest_segment_index=0;
À biggest_segment_pages=0;
” (log) {
sh_log_llog("Max pages count is currently set to 0x",Ê);
á(ï);
È(" pages or 0x");
á(ï*4096);
È(" bytes.\n");
}
// first loop : ident”y memory amount and bigest free region
(À i=0;i<Ü->entry_count;i++) {
À start_page=Ò[i].physical_start/4096;
À end_page=start_page+Ò[i].pages_count;
” (Ò[i].type==ø && Ò[i].pages_count>biggest_segment_pages) {
biggest_segment_pages=Ò[i].pages_count;
biggest_segment_index=i;
}
” (verbose) {
ý("Found memory map segment #",Ê);
à(i);
È(": [0x");
á(start_page*4096);
È(" - 0x");
á(end_page*4096);
È("] Memory type: ");
à(Ò[i].type);
” (Ò[i].type==ø) {
È(" --> usable\n");
} ÷ {
È(" --> not usable\n");
}
” (!(end_page<=ï)) {
sh_log_lwarning("Memory map segment #",Ê);
à(i);
È(" isn't usable because it overflow over max page count. Enable debug log channel to see more.\n");
}
}
” (Ò[i].type==ø && end_page<=ï) {
” (end_page>highest_usable_page) {
highest_usable_segment=i;
highest_usable_page=end_page;
}
}
}
Å=highest_usable_page;
é=Å*Ã;
” (verbose) {
ý("Total memory was given by memory map segment #",Ê);
à(highest_usable_segment);
È("\n");
ý("Total memory (pages): 0x",Ê);
á(Å);
È(". Total memory (bytes) : 0x");
á(é);
È("\n");
}
” (biggest_segment_pages==0) {
ê("No suitable conventional memory segment found.",Ê);
 É;
}
” (Ò[biggest_segment_index].pages_count<(Å/8)) {
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
 É;
}
Í pa=Ò[biggest_segment_index].physical_start;
Ä va;
Ø=Å/8;
” (Å%8!=0) Ø++;
ß=Ø/Ã;
” (Ø%Ã!=0) ß++;
Ñ Ë=ì(ä,SH_PAGE_KERNEL_PERM_VA_BASE,(SH_PAGE_KERNEL_PERM_VA_END-SH_PAGE_KERNEL_PERM_VA_BASE+1-0x1000),ß*Ã,&va);
” (Ë!=Ç) {
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
 Ë;
}
Ë=è(ä,va,pa,Î | SH_PAGE_NX | SH_PAGE_RW,ß*Ã);
” (Ë==É) {
ê("Memory is too low or too fragmented to allocate physical bitmap.",Ê);
 Ë;
} ÷ ” (Ë!=Ç) {
ê("An unknow error happened during physical bitmap pages mapping. See error below",Ê);
 Ë;
}
Þ=(ë*)va;
Ë=sh_mem_set_8(Þ,0xFF,Ø);
” (sh_Ë_error(Ë)) {
ê("An unknow error happened during physical bitmap filling with 0xFF. See error below.",Ê);
 Ë;
}
// second loop : actually set all free regions o physical bitmap
(À i=0;i<Ü->entry_count;i++) {
À start_page=Ò[i].physical_start/4096;
À end_page=start_page+Ò[i].pages_count;
” (end_page<=ï) {
” (Ò[i].type==ø) {
Ñ Ë=Ù(Þ,Å,Ò[i].physical_start/Ã,Ò[i].pages_count,SH_FALSE);
” (sh_Ë_error(Ë)) {
ê("Couldn't set this memory map segment to usable.",Ê);
 Ñ_PMAP_NO_PAGES_SET;
}
}
}
}
Ù(Þ,Å,pa/Ã,ß,SH_TRUE);
 Ç;
}
Ä sh_page_get_Þ_ptr() {
 (Ä)Þ;
}
Ÿ À popcount64(À x) {
x=x-((x>>1) & 0x5555555555555555ULL);
x=(x & 0x3333333333333333ULL)+((x>>2) & 0x3333333333333333ULL);
x=(x+(x>>4)) & 0x0F0F0F0F0F0F0F0FULL;
x=x+(x>>8);
x=x+(x>>16);
x=x+(x>>32);
 x & 0x7F;
}
Ñ sh_page_get_memory_stats(sh_page_MEM_STATS *ç) {
” (ç==Ú) Â Á;
ç->memory_total_pages=Å;
ç->memory_total_bytes=é;
À free_pages=0;
À used_pages=0;
À â=0;
À ã=0;
À õ=0;
À ö=0;
À Ô=0;
À Õ=0;
À full_u64_count=Å/64;
À remaining_bits=Å%64;
À *bitmap64=(À*)Þ;
(À i=0;i<full_u64_count;i++) {
À val=bitmap64[i];
© ones=popcount64(val);
© zeros=64-ones;
used_pages+=ones;
free_pages+=zeros;
( b=0;b<64;b++) {
sh_ƒ bit_set=(val>>b) & 1;
” (bit_set) {
Õ++;
” (Ô) {
õ++;
” (Ô>â) {
â=Ô;
}
Ô=0;
}
} ÷ {
Ô++;
” (Õ) {
ö++;
” (Õ>ã) {
ã=Õ;
}
Õ=0;
}
}
}
}
” (remaining_bits) {
À val=bitmap64[full_u64_count] & ((1ULL<<remaining_bits)-1);
© ones=popcount64(val);
© zeros=remaining_bits-ones;
used_pages+=ones;
free_pages+=zeros;
(À b=0;b<remaining_bits;b++) {
sh_ƒ bit_set=(val>>b) & 1;
” (bit_set) {
Õ++;
” (Ô) {
õ++;
” (Ô>â) {
â=Ô;
}
Ô=0;
}
} ÷ {
Ô++;
” (Õ) {
ö++;
” (Õ>ã) {
ã=Õ;
}
Õ=0;
}
}
}
}
” (Ô) {
õ++;
” (Ô>â) {
â=Ô;
}
}
” (Õ) {
ö++;
” (Õ>ã) {
ã=Õ;
}
}
ç->free_pages=free_pages;
ç->used_pages=used_pages;
ç->free_ratio=(Œ)free_pages/(Œ)Å;
ç->used_ratio=(Œ)used_pages/(Œ)Å;
ç->â=â;
ç->ã=ã;
ç->õ=õ;
ç->ö=ö;
ç->Ø=(Å+7)/8;
ç->ß=(ç->Ø+4095)/4096;
 Ç;