📄 win32.c
字号:
cachedsi.wProcessorRevision = gCpuCaps.cpuStepping; cachedsi.dwNumberOfProcessors = 1; /* hardcoded */ }/* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking fdiv_bug and fpu emulation flags -- alex/MPlayer */#ifdef __linux__ { char buf[20]; char line[200]; FILE *f = fopen ("/proc/cpuinfo", "r"); if (!f) { mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: " "/proc/cpuinfo not readable! " "Expect bad performance and/or weird behaviour\n"); goto exit; } while (fgets(line,200,f)!=NULL) { char *s,*value; /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr(line,':'))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value==' ') value++; if ((s=strchr(value,'\n'))) *s='\0'; /* 2.1 method */ if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) { if (isdigit (value[0])) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } /* old 2.0 method */ if (!lstrncmpiA(line, "cpu",strlen("cpu"))) { if ( isdigit (value[0]) && value[1] == '8' && value[2] == '6' && value[3] == 0 ) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) { if (!lstrncmpiA(value,"yes",3)) PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; continue; } if (!lstrncmpiA(line,"fpu",strlen("fpu"))) { if (!lstrncmpiA(value,"no",2)) PF[PF_FLOATING_POINT_EMULATED] = TRUE; continue; } if (!lstrncmpiA(line,"processor",strlen("processor"))) { /* processor number counts up...*/ unsigned int x; if (sscanf(value,"%d",&x)) if (x+1>cachedsi.dwNumberOfProcessors) cachedsi.dwNumberOfProcessors=x+1; /* Create a new processor subkey on a multiprocessor * system */ sprintf(buf,"%d",x); } if (!lstrncmpiA(line,"stepping",strlen("stepping"))) { int x; if (sscanf(value,"%d",&x)) cachedsi.wProcessorRevision = x; } if ( (!lstrncmpiA(line,"flags",strlen("flags"))) || (!lstrncmpiA(line,"features",strlen("features"))) ) { if (strstr(value,"cx8")) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (strstr(value,"mmx")) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (strstr(value,"tsc")) PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; if (strstr(value,"xmm") || strstr(value,"sse")) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (strstr(value,"sse2")) PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE; if (strstr(value,"3dnow")) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; } } fclose (f); /* * ad hoc fix for smp machines. * some problems on WaitForSingleObject,CreateEvent,SetEvent * CreateThread ...etc.. * */ cachedsi.dwNumberOfProcessors=1; }#endif /* __linux__ */ cache = 1;exit: memcpy(si,&cachedsi,sizeof(*si)); DumpSystemInfo(si);}// avoid undefined expGetSystemInfostatic WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v){ WIN_BOOL result = 0; if (!pf_set) { SYSTEM_INFO si; expGetSystemInfo(&si); } if(v<64) result=PF[v]; dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); return result;}static long WINAPI expGetVersion(){ dbgprintf("GetVersion() => 0xC0000004\n"); return 0xC0000004;//Windows 95}static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size){ // printf("HeapCreate:"); HANDLE result; if(init_size==0) result=(HANDLE)my_mreq(0x110000, 0); else result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0); dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result); return result;}// this is another dirty hack// VP31 is releasing one allocated Heap chunk twice// we will silently ignore this second call...static void* heapfreehack = 0;static int heapfreehackshown = 0;//extern void trapbug(void);static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size){ void* z; /** Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for HeapAlloc returns area larger than size argument :-/ actually according to M$ Doc HeapCreate size should be rounded to page boundaries thus we should simulate this **/ //if (size == 22276) trapbug(); z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY)); if(z==0) printf("HeapAlloc failure\n"); dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z); heapfreehack = 0; // reset return z;}static long WINAPI expHeapDestroy(void* heap){ dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap); my_release(heap); return 1;}static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem){ dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem); if (heapfreehack != lpMem && lpMem != (void*)0xffffffff && lpMem != (void*)0xbdbdbdbd) // 0xbdbdbdbd is for i263_drv.drv && libefence // it seems to be reading from relased memory // EF_PROTECT_FREE doens't show any probleme my_release(lpMem); else { if (!heapfreehackshown++) printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem); } heapfreehack = lpMem; return 1;}static long WINAPI expHeapSize(int heap, int flags, void* pointer){ long result=my_size(pointer); dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result); return result;}static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size){ long orgsize = my_size(lpMem); dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size); return my_realloc(lpMem, size);}static long WINAPI expGetProcessHeap(void){ dbgprintf("GetProcessHeap() => 1\n"); return 1;}static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4){ void* z = VirtualAlloc(v1, v2, v3, v4); if(z==0) printf("VirtualAlloc failure\n"); dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z); return z;}static int WINAPI expVirtualFree(void* v1, int v2, int v3){ int result = VirtualFree(v1,v2,v3); dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result); return result;}/* we're building a table of critical sections. cs_win pointer uses the DLL cs_unix is the real structure, we're using cs_win only to identifying cs_unix */struct critsecs_list_t{ CRITICAL_SECTION *cs_win; struct CRITSECT *cs_unix;};/* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */#undef CRITSECS_NEWTYPE//#define CRITSECS_NEWTYPE 1#ifdef CRITSECS_NEWTYPE/* increased due to ucod needs more than 32 entries *//* and 64 should be enough for everything */#define CRITSECS_LIST_MAX 64static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];static int critsecs_get_pos(CRITICAL_SECTION *cs_win){ int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == cs_win) return(i); return(-1);}static int critsecs_get_unused(void){ int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == NULL) return(i); return(-1);}struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win){ int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix) return(critsecs_list[i].cs_unix); return(NULL);}#endifstatic void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c){ dbgprintf("InitializeCriticalSection(0x%x)\n", c); /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) { printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION)); return; }*/ /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */#ifdef CRITSECS_NEWTYPE { struct CRITSECT *cs; int i = critsecs_get_unused(); if (i < 0) { printf("InitializeCriticalSection(%p) - no more space in list\n", c); return; } dbgprintf("got unused space at %d\n", i); cs = malloc(sizeof(struct CRITSECT)); if (!cs) { printf("InitializeCriticalSection(%p) - out of memory\n", c); return; } pthread_mutex_init(&cs->mutex, NULL); cs->locked = 0; critsecs_list[i].cs_win = c; critsecs_list[i].cs_unix = cs; dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n", i, c, cs); }#else { struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION), 0, AREATYPE_CRITSECT); pthread_mutex_init(&cs->mutex, NULL); cs->locked=0; cs->deadbeef = 0xdeadbeef; *(void**)c = cs; }#endif return;}static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c){#ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c);#else struct CRITSECT* cs = (*(struct CRITSECT**)c);#endif dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs); if (!cs) { dbgprintf("entered uninitialized critisec!\n"); expInitializeCriticalSection(c);#ifdef CRITSECS_NEWTYPE cs=critsecs_get_unix(c);#else cs = (*(struct CRITSECT**)c);#endif dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c); } if(cs->locked) if(cs->id==pthread_self()) return; pthread_mutex_lock(&(cs->mutex)); cs->locked=1; cs->id=pthread_self(); return;}static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c){#ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c);#else struct CRITSECT* cs = (*(struct CRITSECT**)c);#endif // struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs); if (!cs) { dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c); return; } if (cs->locked) { cs->locked=0; pthread_mutex_unlock(&(cs->mutex)); } else dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c); return;}static void expfree(void* mem); /* forward declaration */static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c){#ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c);#else struct CRITSECT* cs= (*(struct CRITSECT**)c);#endif // struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("DeleteCriticalSection(0x%x)\n",c); if (!cs) { dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c); return; } if (cs->locked) { dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c); pthread_mutex_unlock(&(cs->mutex)); }#ifndef GARBAGE pthread_mutex_destroy(&(cs->mutex)); // released by GarbageCollector in my_relase otherwise#endif my_release(cs);#ifdef CRITSECS_NEWTYPE { int i = critsecs_get_pos(c); if (i < 0) { printf("DeleteCriticalSection(%p) error (critsec not found)\n", c); return; } critsecs_list[i].cs_win = NULL; expfree(critsecs_list[i].cs_unix); critsecs_list[i].cs_unix = NULL; dbgprintf("DeleteCriticalSection -> itemno=%d\n", i); }#endif return;}static int WINAPI expGetCurrentThreadId(){ dbgprintf("GetCurrentThreadId() => %d\n", pthread_self()); return pthread_self();}static int WINAPI expGetCurrentProcess(){ dbgprintf("GetCurrentProcess() => %d\n", getpid()); return getpid();}#ifdef QTX// this version is required for Quicktime codecs (.qtx/.qts) to work.// (they assume some pointers at FS: segment)extern void* fs_seg;//static int tls_count;static int tls_use_map[64];static int WINAPI expTlsAlloc(){ int i; for(i=0; i<64; i++) if(tls_use_map[i]==0) { tls_use_map[i]=1; dbgprintf("TlsAlloc() => %d\n",i); return i; } dbgprintf("TlsAlloc() => -1 (ERROR)\n"); return -1;}//static int WINAPI expTlsSetValue(DWORD index, void* value)static int WINAPI expTlsSetValue(int index, void* value){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -