Mercurial > mplayer.hg
comparison loader/win32.c @ 1307:d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
attribute mismatch between caller/caller. wine/loader is less sensitive to
optimization now. (now that avifile-0.6 has the same patch installed, we're
a bit closer to their CVS tree)
Speed up win32 "QueryPerformanceFrequency" emulation on solaris.
author | jkeil |
---|---|
date | Thu, 12 Jul 2001 15:27:48 +0000 |
parents | bf973bffe240 |
children | 8e841fe5668b |
comparison
equal
deleted
inserted
replaced
1306:7ce37211e454 | 1307:d8c1b0b38edc |
---|---|
26 #include <unistd.h> | 26 #include <unistd.h> |
27 #include <fcntl.h> | 27 #include <fcntl.h> |
28 #include <sys/types.h> | 28 #include <sys/types.h> |
29 #include <sys/time.h> | 29 #include <sys/time.h> |
30 #include <sys/timeb.h> | 30 #include <sys/timeb.h> |
31 #if HAVE_LIBKSTAT | |
32 #include <kstat.h> | |
33 #endif | |
31 | 34 |
32 #include <wine/winbase.h> | 35 #include <wine/winbase.h> |
33 #include <wine/winreg.h> | 36 #include <wine/winreg.h> |
34 #include <wine/winnt.h> | 37 #include <wine/winnt.h> |
35 #include <wine/winerror.h> | 38 #include <wine/winerror.h> |
75 "movl %%eax, 0(%%ebx)\n\t" | 78 "movl %%eax, 0(%%ebx)\n\t" |
76 "movl %%edx, 4(%%ebx)\n\t" | 79 "movl %%edx, 4(%%ebx)\n\t" |
77 "popl %%ebx\n\t" | 80 "popl %%ebx\n\t" |
78 ::"a"(z)); | 81 ::"a"(z)); |
79 } | 82 } |
80 #include <sys/time.h> | |
81 #include <unistd.h> | |
82 static unsigned int c_localcount_notsc() | 83 static unsigned int c_localcount_notsc() |
83 { | 84 { |
84 struct timeval tv; | 85 struct timeval tv; |
85 unsigned limit=~0; | 86 unsigned limit=~0; |
86 limit/=1000000; | 87 limit/=1000000; |
98 result=tv.tv_sec; | 99 result=tv.tv_sec; |
99 result<<=32; | 100 result<<=32; |
100 result+=limit*tv.tv_usec; | 101 result+=limit*tv.tv_usec; |
101 *z=result; | 102 *z=result; |
102 } | 103 } |
103 static unsigned int localcount_stub(); | 104 |
104 static void longcount_stub(long long*); | 105 static unsigned int localcount_stub(void); |
106 static void longcount_stub(long long* z); | |
105 static unsigned int (*localcount)()=localcount_stub; | 107 static unsigned int (*localcount)()=localcount_stub; |
106 static void (*longcount)(long long*)=longcount_stub; | 108 static void (*longcount)(long long*)=longcount_stub; |
107 | 109 |
108 static unsigned int localcount_stub() | 110 static unsigned int localcount_stub(void) |
109 { | 111 { |
110 unsigned int regs[4]; | 112 unsigned int regs[4]; |
111 do_cpuid(regs); | 113 do_cpuid(regs); |
112 if ((regs[3] & 0x00000010) == 0) | 114 if ((regs[3] & 0x00000010) == 0) |
113 { | 115 { |
137 } | 139 } |
138 longcount(z); | 140 longcount(z); |
139 } | 141 } |
140 | 142 |
141 int LOADER_DEBUG=1; | 143 int LOADER_DEBUG=1; |
142 inline void dbgprintf(char* fmt, ...) | 144 static inline void dbgprintf(char* fmt, ...) |
143 { | 145 { |
144 #ifdef DETAILED_OUT | 146 #ifdef DETAILED_OUT |
145 if(LOADER_DEBUG) | 147 if(LOADER_DEBUG) |
146 { | 148 { |
147 FILE* f; | 149 FILE* f; |
166 }; | 168 }; |
167 //#define min(x,y) ((x)<(y)?(x):(y)) | 169 //#define min(x,y) ((x)<(y)?(x):(y)) |
168 | 170 |
169 static unsigned char* heap=NULL; | 171 static unsigned char* heap=NULL; |
170 static int heap_counter=0; | 172 static int heap_counter=0; |
171 void test_heap() | 173 static void test_heap() |
172 { | 174 { |
173 int offset=0; | 175 int offset=0; |
174 if(heap==0) | 176 if(heap==0) |
175 return; | 177 return; |
176 while(offset<heap_counter) | 178 while(offset<heap_counter) |
324 | 326 |
325 extern int unk_exp1; | 327 extern int unk_exp1; |
326 char extcode[20000];// place for 200 unresolved exports | 328 char extcode[20000];// place for 200 unresolved exports |
327 int pos=0; | 329 int pos=0; |
328 | 330 |
329 int WINAPI ext_unknown() | 331 int WINAPI ext_unknown(void) |
330 { | 332 { |
331 printf("Unknown func called\n"); | 333 printf("Unknown func called\n"); |
332 return 0; | 334 return 0; |
333 } | 335 } |
334 int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) | 336 int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) |
401 { | 403 { |
402 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); | 404 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); |
403 return 0; | 405 return 0; |
404 } | 406 } |
405 | 407 |
406 typedef struct { | |
407 unsigned int uDriverSignature; | |
408 void* hDriverModule; | |
409 void* DriverProc; | |
410 unsigned int dwDriverID; | |
411 } DRVR; | |
412 | |
413 void* WINAPI expGetDriverModuleHandle(DRVR* pdrv) | 408 void* WINAPI expGetDriverModuleHandle(DRVR* pdrv) |
414 { | 409 { |
415 void* result; | 410 void* result; |
416 if (pdrv==NULL) result=NULL; | 411 if (pdrv==NULL) |
417 result=pdrv->hDriverModule; | 412 result=NULL; |
413 else | |
414 result=(void*) pdrv->hDriverModule; | |
418 dbgprintf("GetDriverModuleHandle(0x%x) => 0x%x\n", pdrv, result); | 415 dbgprintf("GetDriverModuleHandle(0x%x) => 0x%x\n", pdrv, result); |
419 return result; | 416 return result; |
420 } | 417 } |
421 | 418 |
422 void* WINAPI expGetModuleHandleA(const char* name) | 419 void* WINAPI expGetModuleHandleA(const char* name) |
990 int WINAPI expGetCurrentProcess() | 987 int WINAPI expGetCurrentProcess() |
991 { | 988 { |
992 dbgprintf("GetCurrentProcess() => %d\n", getpid()); | 989 dbgprintf("GetCurrentProcess() => %d\n", getpid()); |
993 return getpid(); | 990 return getpid(); |
994 } | 991 } |
995 struct tls_s; | 992 |
996 typedef struct tls_s | 993 struct tls_s |
997 { | 994 { |
998 void* value; | 995 void* value; |
999 int used; | 996 int used; |
1000 struct tls_s* prev; | 997 struct tls_s* prev; |
1001 struct tls_s* next; | 998 struct tls_s* next; |
1002 }tls_t; | 999 }; |
1003 | |
1004 tls_t* g_tls=NULL; | 1000 tls_t* g_tls=NULL; |
1005 | 1001 |
1006 void* WINAPI expTlsAlloc() | 1002 void* WINAPI expTlsAlloc() |
1007 { | 1003 { |
1008 if(g_tls==NULL) | 1004 if(g_tls==NULL) |
1129 s1++; | 1125 s1++; |
1130 } | 1126 } |
1131 result=i; | 1127 result=i; |
1132 } | 1128 } |
1133 if(s1) | 1129 if(s1) |
1134 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s', | 1130 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s', " |
1135 size %d, dest buffer 0x%x, dest size %d) => %d\n", | 1131 "size %d, dest buffer 0x%x, dest size %d) => %d\n", |
1136 v1, v2, s1, s1, siz1, s2, siz2, result); | 1132 v1, v2, s1, s1, siz1, s2, siz2, result); |
1137 else | 1133 else |
1138 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL, | 1134 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL, " |
1139 size %d, dest buffer 0x%x, dest size %d) =>\n", | 1135 "size %d, dest buffer 0x%x, dest size %d) =>\n", |
1140 v1, v2, siz1, s2, siz2, result); | 1136 v1, v2, siz1, s2, siz2, result); |
1141 return result; | 1137 return result; |
1142 } | 1138 } |
1143 static void wch_print(const short* str) | 1139 static void wch_print(const short* str) |
1144 { | 1140 { |
1303 longcount(z); | 1299 longcount(z); |
1304 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z); | 1300 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z); |
1305 return 1; | 1301 return 1; |
1306 } | 1302 } |
1307 | 1303 |
1308 static double old_freq() | 1304 /* |
1305 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo) | |
1306 */ | |
1307 static double linux_cpuinfo_freq() | |
1308 { | |
1309 double freq=-1; | |
1310 FILE *f; | |
1311 char line[200]; | |
1312 char *s,*value; | |
1313 | |
1314 f = fopen ("/proc/cpuinfo", "r"); | |
1315 if (f != NULL) { | |
1316 while (fgets(line,sizeof(line),f)!=NULL) { | |
1317 /* NOTE: the ':' is the only character we can rely on */ | |
1318 if (!(value = strchr(line,':'))) | |
1319 continue; | |
1320 /* terminate the valuename */ | |
1321 *value++ = '\0'; | |
1322 /* skip any leading spaces */ | |
1323 while (*value==' ') value++; | |
1324 if ((s=strchr(value,'\n'))) | |
1325 *s='\0'; | |
1326 | |
1327 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz")) | |
1328 && sscanf(value, "%lf", &freq) == 1) { | |
1329 freq*=1000; | |
1330 break; | |
1331 } | |
1332 } | |
1333 fclose(f); | |
1334 } | |
1335 return freq; | |
1336 } | |
1337 | |
1338 | |
1339 static double | |
1340 solaris_kstat_freq() | |
1341 { | |
1342 #if HAVE_LIBKSTAT | |
1343 /* | |
1344 * try to extract the CPU speed from the solaris kernel's kstat data | |
1345 */ | |
1346 kstat_ctl_t *kc; | |
1347 kstat_t *ksp; | |
1348 kstat_named_t *kdata; | |
1349 int mhz = 0; | |
1350 | |
1351 kc = kstat_open(); | |
1352 if (kc != NULL) | |
1353 { | |
1354 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0"); | |
1355 | |
1356 /* kstat found and name/value pairs? */ | |
1357 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED) | |
1358 { | |
1359 /* read the kstat data from the kernel */ | |
1360 if (kstat_read(kc, ksp, NULL) != -1) | |
1361 { | |
1362 /* | |
1363 * lookup desired "clock_MHz" entry, check the expected | |
1364 * data type | |
1365 */ | |
1366 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz"); | |
1367 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32) | |
1368 mhz = kdata->value.i32; | |
1369 } | |
1370 } | |
1371 kstat_close(kc); | |
1372 } | |
1373 | |
1374 if (mhz > 0) | |
1375 return mhz * 1000.; | |
1376 #endif /* HAVE_LIBKSTAT */ | |
1377 return -1; // kstat stuff is not available, CPU freq is unknown | |
1378 } | |
1379 | |
1380 /* | |
1381 * Measure CPU freq using the pentium's time stamp counter register (TSC) | |
1382 */ | |
1383 static double tsc_freq() | |
1309 { | 1384 { |
1310 static double ofreq=0.0; | 1385 static double ofreq=0.0; |
1311 int i; | 1386 int i; |
1312 int x,y; | 1387 int x,y; |
1313 i=time(NULL); | 1388 i=time(NULL); |
1318 while(i==time(NULL)); | 1393 while(i==time(NULL)); |
1319 y=localcount(); | 1394 y=localcount(); |
1320 ofreq = (double)(y-x)/1000.; | 1395 ofreq = (double)(y-x)/1000.; |
1321 return ofreq; | 1396 return ofreq; |
1322 } | 1397 } |
1398 | |
1323 static double CPU_Freq() | 1399 static double CPU_Freq() |
1324 { | 1400 { |
1325 //#ifdef USE_TSC | 1401 double freq; |
1326 FILE *f = fopen ("/proc/cpuinfo", "r"); | |
1327 char line[200]; | |
1328 char model[200]="unknown"; | |
1329 char flags[500]=""; | |
1330 char *s,*value; | |
1331 double freq=-1; | |
1332 | 1402 |
1333 if (!f) | 1403 if ((freq = linux_cpuinfo_freq()) > 0) |
1334 { | |
1335 //printf("Can't open /proc/cpuinfo for reading\n"); | |
1336 return old_freq(); | |
1337 } | |
1338 while (fgets(line,200,f)!=NULL) | |
1339 { | |
1340 /* NOTE: the ':' is the only character we can rely on */ | |
1341 if (!(value = strchr(line,':'))) | |
1342 continue; | |
1343 /* terminate the valuename */ | |
1344 *value++ = '\0'; | |
1345 /* skip any leading spaces */ | |
1346 while (*value==' ') value++; | |
1347 if ((s=strchr(value,'\n'))) | |
1348 *s='\0'; | |
1349 | |
1350 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))) | |
1351 { | |
1352 sscanf(value, "%lf", &freq); | |
1353 freq*=1000; | |
1354 break; | |
1355 } | |
1356 continue; | |
1357 | |
1358 } | |
1359 fclose(f); | |
1360 if(freq<0)return old_freq(); | |
1361 return freq; | 1404 return freq; |
1362 //#else | 1405 |
1363 // return old_freq(); | 1406 if ((freq = solaris_kstat_freq()) > 0) |
1364 //#endif | 1407 return freq; |
1408 | |
1409 return tsc_freq(); | |
1365 } | 1410 } |
1366 | 1411 |
1367 long WINAPI expQueryPerformanceFrequency(long long* z) | 1412 long WINAPI expQueryPerformanceFrequency(long long* z) |
1368 { | 1413 { |
1369 *z=(long long)CPU_Freq(); | 1414 *z=(long long)CPU_Freq(); |
1656 long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, | 1701 long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, |
1657 long flProtect, long dwMaxHigh, long dwMaxLow, const char* name) | 1702 long flProtect, long dwMaxHigh, long dwMaxLow, const char* name) |
1658 { | 1703 { |
1659 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); | 1704 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); |
1660 if(!name) | 1705 if(!name) |
1661 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, | 1706 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, " |
1662 flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n", | 1707 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n", |
1663 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result); | 1708 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result); |
1664 else | 1709 else |
1665 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, | 1710 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, " |
1666 flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n", | 1711 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n", |
1667 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result); | 1712 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result); |
1668 return result; | 1713 return result; |
1669 } | 1714 } |
1670 | 1715 |
1671 long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) | 1716 long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) |
2744 // return (void*)extcode; | 2789 // return (void*)extcode; |
2745 // printf("Unknown func %s:%s\n", library, name); | 2790 // printf("Unknown func %s:%s\n", library, name); |
2746 // return (void*)ext_unknown; | 2791 // return (void*)ext_unknown; |
2747 } | 2792 } |
2748 | 2793 |
2749 int my_garbagecollection() | 2794 int my_garbagecollection(void) |
2750 { | 2795 { |
2751 #ifdef GARBAGE | 2796 #ifdef GARBAGE |
2752 alc_list* pp,*ppsv; | 2797 alc_list* pp,*ppsv; |
2753 mutex_list* pm,*pmsv; | 2798 mutex_list* pm,*pmsv; |
2754 int unfree,unfreecnt; | 2799 int unfree,unfreecnt; |