Changeset 129 for trunk/src/helpers/dosh.c
- Timestamp:
- Jan 8, 2002, 7:29:57 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dosh.c
r127 r129 1814 1814 = pFile->cbCurrent 1815 1815 = *pcbFile; 1816 1817 pFile->pszFilename = strdup(pcszFilename); 1816 1818 } 1817 1819 else … … 1878 1880 * method). 1879 1881 * 1882 * This implements a small cache so that several 1883 * calls with a near offset will not touch the 1884 * disk always. The cache has been optimized for 1885 * the exeh* functions and works quite nicely 1886 * there. 1887 * 1888 * Note that the position of the file pointer is 1889 * undefined after calling this function because 1890 * the data might have been returned from the 1891 * cache. 1892 * 1880 1893 *@@added V0.9.13 (2001-06-14) [umoeller] 1881 1894 *@@changed V0.9.16 (2001-12-18) [umoeller]: now with XFILE, and always using FILE_BEGIN … … 1895 1908 *pcb = 0; 1896 1909 1897 if (!(arc = DosSetFilePtr(pFile->hf, 1898 (LONG)ulOffset, 1899 FILE_BEGIN, 1900 &ulDummy))) 1910 // check if we have the data in the cache already; 1911 1912 if ( (pFile->pbCache) 1913 // first byte must be in cache 1914 && (ulOffset >= pFile->ulReadFrom) 1915 // last byte must be in cache 1916 && ( ulOffset + cb 1917 <= pFile->ulReadFrom + pFile->cbCache 1918 ) 1919 ) 1901 1920 { 1902 if (!(arc = DosRead(pFile->hf, 1903 pbData, 1904 cb, 1905 &ulDummy))) 1906 *pcb = ulDummy; // bytes read 1921 // alright, return data from cache simply 1922 ULONG ulOfsInCache = ulOffset - pFile->ulReadFrom; 1923 1924 memcpy(pbData, 1925 pFile->pbCache + ulOfsInCache, 1926 cb); 1927 *pcb = cb; 1928 1929 _Pmpf((__FUNCTION__ " %s: data is fully in cache", 1930 pFile->pszFilename)); 1931 _Pmpf((" caller wants %d bytes from %d", 1932 cb, ulOffset)); 1933 _Pmpf((" we got %d bytes from %d", 1934 pFile->cbCache, pFile->ulReadFrom)); 1935 _Pmpf((" so copied %d bytes from cache ofs %d", 1936 cb, ulOfsInCache)); 1937 1938 // still, advance the file pointer because 1939 // caller might run plain DosRead next 1940 /* DosSetFilePtr(pFile->hf, 1941 (LONG)ulOffset + cb, 1942 FILE_BEGIN, 1943 &ulDummy); */ 1944 } 1945 else 1946 { 1947 // data is not in cache: 1948 // check how much it is... for small amounts, 1949 // we load the cache first 1950 if (cb <= 4096 - 512) 1951 { 1952 _Pmpf((__FUNCTION__ " %s: filling cache anew", 1953 pFile->pszFilename)); 1954 _Pmpf((" caller wants %d bytes from %d", 1955 cb, ulOffset)); 1956 1957 // OK, then fix the offset to read from 1958 // to a multiple of 512 to get a full sector 1959 pFile->ulReadFrom = ulOffset / 512L * 512L; 1960 // and read 4096 bytes always plus the 1961 // value we cut off above 1962 pFile->cbCache = 4096; 1963 1964 _Pmpf((" getting %d bytes from %d", 1965 pFile->cbCache, pFile->ulReadFrom)); 1966 1967 // free old cache 1968 if (pFile->pbCache) 1969 free(pFile->pbCache); 1970 1971 // allocate new cache 1972 if (!(pFile->pbCache = (PBYTE)malloc(pFile->cbCache))) 1973 arc = ERROR_NOT_ENOUGH_MEMORY; 1974 else 1975 { 1976 if (!(arc = DosSetFilePtr(pFile->hf, 1977 (LONG)pFile->ulReadFrom, 1978 FILE_BEGIN, 1979 &ulDummy))) 1980 { 1981 if (!(arc = DosRead(pFile->hf, 1982 pFile->pbCache, 1983 pFile->cbCache, 1984 &ulDummy))) 1985 { 1986 // got data: 1987 ULONG ulOfsInCache; 1988 1989 _Pmpf((" %d bytes read", ulDummy)); 1990 pFile->cbCache = ulDummy; 1991 1992 // copy to caller 1993 ulOfsInCache = ulOffset - pFile->ulReadFrom; 1994 memcpy(pbData, 1995 pFile->pbCache + ulOfsInCache, 1996 cb); 1997 *pcb = cb; 1998 1999 _Pmpf((" so copied %d bytes from cache ofs %d", 2000 cb, ulOfsInCache)); 2001 2002 // still, advance the file pointer because 2003 // caller might run plain DosRead next 2004 /* DosSetFilePtr(pFile->hf, 2005 (LONG)ulOffset + cb, 2006 FILE_BEGIN, 2007 &ulDummy); */ 2008 } 2009 } 2010 2011 if (arc) 2012 FREE(pFile->pbCache); 2013 } 2014 } 2015 else 2016 { 2017 // read uncached: 2018 _Pmpf((" " __FUNCTION__ " %s: reading uncached", 2019 pFile->pszFilename)); 2020 _Pmpf((" caller wants %d bytes from %d", 2021 cb, ulOffset)); 2022 if (!(arc = DosSetFilePtr(pFile->hf, 2023 (LONG)ulOffset, 2024 FILE_BEGIN, 2025 &ulDummy))) 2026 { 2027 if (!(arc = DosRead(pFile->hf, 2028 pbData, 2029 cb, 2030 &ulDummy))) 2031 *pcb = ulDummy; // bytes read 2032 } 2033 } 1907 2034 } 1908 2035 … … 2003 2130 cb, 2004 2131 &cbWritten))) 2132 { 2005 2133 pFile->cbCurrent += cbWritten; 2134 // invalidate the cache 2135 FREE(pFile->pbCache); 2136 } 2006 2137 2007 2138 doshUnlockFile(pFile); … … 2137 2268 *ppFile = NULL; 2138 2269 2270 FREE(pFile->pbCache); 2271 FREE(pFile->pszFilename); 2272 2139 2273 if (pFile->hf) 2140 2274 { … … 2162 2296 * buffer (or NULL upon errors). 2163 2297 * 2298 * This allocates one extra byte to make the 2299 * buffer null-terminated always. The buffer 2300 * is _not_ converted WRT the line format. 2301 * 2164 2302 * This returns the APIRET of DosOpen and DosRead. 2165 2303 * If any error occured, no buffer was allocated. … … 2168 2306 * 2169 2307 *@@changed V0.9.7 (2001-01-15) [umoeller]: renamed from doshReadTextFile 2170 */ 2171 2172 APIRET doshLoadTextFile(PCSZ pcszFile, // in: file name to read 2173 PSZ* ppszContent) // out: newly allocated buffer with file's content 2174 { 2308 *@@changed V0.9.16 (2002-01-05) [umoeller]: added pcbRead 2309 *@@changed V0.9.16 (2002-01-05) [umoeller]: rewritten using doshOpen 2310 */ 2311 2312 APIRET doshLoadTextFile(PCSZ pcszFile, // in: file name to read 2313 PSZ* ppszContent, // out: newly allocated buffer with file's content 2314 PULONG pcbRead) // out: size of that buffer including null byte (ptr can be NULL) 2315 { 2316 APIRET arc; 2317 2318 ULONG cbFile = 0; 2319 PXFILE pFile = NULL; 2320 2321 if (!(arc = doshOpen(pcszFile, 2322 XOPEN_READ_EXISTING, 2323 &cbFile, 2324 &pFile))) 2325 { 2326 PSZ pszContent; 2327 if (!(pszContent = (PSZ)malloc(cbFile + 1))) 2328 arc = ERROR_NOT_ENOUGH_MEMORY; 2329 else 2330 { 2331 ULONG cbRead = 0; 2332 if (!(arc = DosRead(pFile->hf, 2333 pszContent, 2334 cbFile, 2335 &cbRead))) 2336 { 2337 if (cbRead != cbFile) 2338 arc = ERROR_NO_DATA; 2339 else 2340 { 2341 pszContent[cbRead] = '\0'; 2342 *ppszContent = pszContent; 2343 } 2344 } 2345 2346 if (arc) 2347 free(pszContent); 2348 } 2349 2350 doshClose(&pFile); 2351 } 2352 2353 /* 2175 2354 ULONG ulSize, 2176 2355 ulBytesRead = 0, … … 2210 2389 // set output buffer pointer 2211 2390 *ppszContent = pszContent; 2391 2392 if (pcbRead) 2393 *pcbRead = ulBytesRead + 1; 2212 2394 } 2213 2395 … … 2217 2399 DosClose(hFile); 2218 2400 } 2401 */ 2219 2402 2220 2403 return (arc); … … 2819 3002 * versions. I believe it came up with some Warp 4 2820 3003 * fixpak. The API is resolved dynamically by 2821 * this function (using DosQueryProcAddr). Only 2822 * if NO_ERROR is returned, you may call doshPerfGet 2823 * afterwards. 3004 * this function (using DosQueryProcAddr). 2824 3005 * 2825 3006 * This properly initializes the internal counters … … 2835 3016 * which have exactly cProcessors array items. 2836 3017 * 3018 * So after NO_ERROR was returned here, you can keep 3019 * calling doshPerfGet to get a current snapshot of the 3020 * IRQ and user loads for each CPU. Note that interrupts 3021 * are only processed on CPU 0 on SMP systems. 3022 * 2837 3023 * Call doshPerfClose to clean up resources allocated 2838 3024 * by this function. 2839 3025 * 3026 * For more sample code, take a look at the "Pulse" widget 3027 * in the XWorkplace sources (src\xcenter\w_pulse.c). 3028 * 2840 3029 * Example code: 2841 3030 * 2842 3031 + PDOSHPERFSYS pPerf = NULL; 2843 + APIRET arc = doshPerfOpen(&pPerf);2844 + if ( arc == NO_ERROR)3032 + APIRET arc; 3033 + if (!(arc = arc = doshPerfOpen(&pPerf))) 2845 3034 + { 2846 + // this should really be in a timer 3035 + // this should really be in a timer, 3036 + // e.g. once per second 2847 3037 + ULONG ulCPU; 2848 + arc = doshPerfGet(&pPerf); 2849 + // go thru all CPUs 2850 + for (ulCPU = 0; ulCPU < pPerf->cProcessors; ulCPU++) 3038 + if (!(arc = doshPerfGet(&pPerf))) 2851 3039 + { 2852 + LONG lLoadThis = pPerf->palLoads[ulCPU]; 2853 + ... 3040 + // go thru all CPUs 3041 + for (ulCPU = 0; ulCPU < pPerf->cProcessors; ulCPU++) 3042 + { 3043 + LONG lUserLoadThis = pPerf->palLoads[ulCPU]; 3044 + ... 3045 + } 2854 3046 + } 2855 +2856 + ...2857 3047 + 2858 3048 + // clean up … … 3014 3204 3015 3205 // avoid division by zero 3016 double dTimeDelta = (dTime - *pdTimePrevThis);3017 if (dTimeDelta )3206 double dTimeDelta; 3207 if (dTimeDelta = (dTime - *pdTimePrevThis)) 3018 3208 { 3019 3209 pPerfSys->palLoads[ul] … … 3060 3250 { 3061 3251 APIRET arc = NO_ERROR; 3062 PDOSHPERFSYS pPerfSys = *ppPerfSys; 3063 if (!pPerfSys) 3252 PDOSHPERFSYS pPerfSys; 3253 if ( (!ppPerfSys) 3254 || (!(pPerfSys = *ppPerfSys)) 3255 ) 3064 3256 arc = ERROR_INVALID_PARAMETER; 3065 3257 else
Note:
See TracChangeset
for help on using the changeset viewer.