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;