Использование High Memory в OS/2 |
Евгений Коцюба, 2003
|
Проблема, вызванная отсутствием проблем с памятью Один из вечных вопросов программирования в DOS - память, а точнее ее нехватка. Вечные свопинги на диск перед запуском другой программы, копание во временных файлах, работа с данными по маленьким кусочкам - все это отнимает массу времени и заставляет идти на ухищрения при решении, казалось бы, элементарных программистских задач. При программировании в операционных средах с виртуальной памятью (а к таковым принадлежит и OS/2) все это совершенно не имеет смысла до тех пор, пока размеры данных не приближаются к пределу адресного пространства процессов (для текущей версии OS/2 - около 512 мегабайтов, в будущих версиях предполагается увеличение). Забудьте про временные файлы, и пусть ничто не остановит вас перед, скажем, такой последовательностью операторов: int fd = open (filename,mode);( Не забудьте, что это - 32-битовый мир, и параметр sizeof третьего аргумента функции read равен 4, как и параметр long.) |
так как система сама ругнется на нехватку памяти. Отсутствие лишней проверки несколько упрощает жизнь программисту и улучшает компактность и читаемость кода.char * input = malloc(size_of_file);
if(input == NULL)
{ printf("Error: malloc кердык\n");
exit(1);
}
RAM eat:246Mb RAM eat:247Mb RAM eat:248Mb Error1: malloc кердык 15675:263.3086Mb: Error2: malloc кердык 5216:263.467804Mb: |
19 Maximum number of bytes of memory that can be allocated by all processes in the system 529948672 20 Maximum number of bytes of memory that this process can allocate in its private arena. 318111744 21 Maximum number of bytes of memory that a process can allocate in the shared arena. 193331200 | 19 Maximum number of bytes of memory that can be allocated by all processes in the system 2068 279 296 20 Maximum number of bytes of memory that this process can allocate in its private arena. 271450112 21 Maximum number of bytes of memory that a process can allocate in the shared arena. 231538688 |
Revision 14.088 |
Revision 9.032 |
A new config.sys parameter, VIRTUALADDRESSLIMIT,
has been added to specify the highest virtual memory
address that may be accessed. The default value for OS/2
Warp Server for SMP is 2 GB, which is specified in megabytes
in the command argument:
VIRTUALADDRESSLIMIT=2048 The smallest value allowed is 512, which provides compatability with previous versions of OS/2 which only allowed access to 512 MB. The largest value supported is 3072 (3 GB). The VIRTUALADDRESSLIMIT parameter may be specified as part of selective install. Values in excess of 512 will reduce the number of processes that can concurrently run on the system. When memory has been exhausted, OS/2 control program functions will fail with ERROR_NOT_ENOUGH_MEMORY and PM functions will fail with PMERR_INSUFFICIENT_MEMORY. This information can be found in the SMP programming addendum, shipped as part of the Warp SMP toolkit (SMP.INF). |
26 Number of processors in the machine 1 27 Maximum amount of free space in process's high private arena 2348810240 28 Maximum amount of free space in process's high shared arena 2348810240 29 Maximum number of concurrent processes supported 172 30 Size of the user's address space in megabytes 3072 |
(To activate HMS in your application, use the attribute OBJ_ANY with the memory allocation functions!)
APIRET result;
PCHAR lowp = NULL;
ULONG i, size;
size = 1024*1024;
result = DosAllocMem((PPVOID)&lowp,size,
PAG_COMMIT | PAG_WRITE | OBJ_ANY)
Таким образом можно сосредоточить все функции для работы с памятью в одном месте, а затем легким движением руки заменить вызов malloc на что-то другое. Далее обращаемся к документации Visual Age C++, раздел Managing Memory With Multiple Heaps:void *
_mesa_malloc(size_t bytes)
{
#if defined(XFree86LOADER) && defined(IN_MODULE)
return xf86malloc(bytes);
#else
return malloc(bytes);
#endif
}
VisualAge C++ now gives you the option of creating
and using your own pools of memory, called heaps. You can use your own heaps
in place of or in addition to the default VisualAge C++ runtime heap to improve
the performance of your program. This section describes how to implement
multiple user-created heaps using VisualAge C++. Note: Many readers will not be interested in creating their own heaps. Using your own heaps is entirely optional, and your applications will work perfectly well using the default memory management provided (and used by) the VisualAge C++ runtime library. If you want to improve the performance and memory management of your program, multiple heaps can help you. Otherwise, you can ignore this section and any heap-specific library functions. |
#include <umalloc.h> Heap_t _ucreate(void *block, size_t initsz, int clean, int memtype, |
Language Level: Extension _ucreate creates your own memory heap that you can allocate and free memory from, just like the VisualAge C++ runtime heap. Before you call _ucreate, you must first get the initial block of memory for the heap. You can get this block by calling an OS/2 API (such as DosAllocMem or or DosAllocSharedMem) or by statically allocating it. (See the CP Programming Guide and Reference for more information on the OS/2 APIs.)
When you call _umalloc (or a similar function) for your heap, if not enough memory is available in the block, it calls the getmore_fn you provide. Your getmore_fn then gets more memory from the system and adds it to the heap, using any method you choose. Your getmore_fn must have the following prototype: void *(*getmore_fn)(Heap_t uh, size_t *size, int *clean); where:
When you call _uheapmin to coalesce the heap or _udestroy to destroy it, these functions call the release_fn you provide to return the memory to the system. function. Your release_fn must have the following prototype: void (*release_fn)(Heap_t uh, void *block, size_t size); The heap uh the block is from, the block to be returned, and its size are passed to release_fn by _uheapmin or _udestroy. For more information about creating and using heaps, see the "Managing Memory" in the Programming Guide. Return Value: If successful, _ucreate returns a pointer to the heap created. If errors occur, _ucreate returns NULL. |