Відкрита пам'ять
Найпростіший варіант управління пам'яттю — відсутність диспетчера пам'яті
і можливість завантажувати в системі лише один процес. Саме так працюють
Ср/м і Rt-ll SJ (Single-job, однозадачна). У цих системах програми
завантажуються з фіксованої адреси Prog_start.
У Ср/м це ОХЮО; у Rt-ll — 01000. По адресах від 0 до початку програми
знаходяться вектори переривань, а в Rt-11 — також і стек програми. Операційна
система розміщується в старших адресах пам'яті. Адреса Sys_start
з якого вона починається, залежить від кількості пам'яті в машини і від
конфігурації ОС (мал. 4.1).

Мал. 4.1. Управління пам'яттю в однопроцессной ОС з відкритою
пам'яттю
В цьому випадку управління пам'яттю з боку системи полягає в тому, що
завантажувач перевіряє, чи поміститься завантажуваний модуль в простір від
Prog_start до
Sys_start . Якщо об'єм пам'яті, який використовує програма,
не мінятиметься під час її виконання, то на цьому все управління і закінчується.
Проте програма може використовувати динамічне управління пам'яттю, наприклад
функцію malloco або щось в цьому роді. В цьому випадку вже код maiioco
повинен стежити за тим, щоб не залізти в системні адреси. Як правило,
динамічна пам'ять починає розміщуватися з адреси Prog_end =
Prog_start + Prog_size. Frog_size в даному випадку
позначає повний розмір програми, тобто розмір її коди, статичних даних і області,
виділеної під стек.
Функція malloc () підтримує деяку структуру даних,
що стежить за тим, які блоки пам'яті з вже виділених були визволені.
При кожному новому запиті вона спочатку шукає блок відповідного розміру в своїй
структурі даних і, лише коли цей пошук завершиться невдачею, просить
нову ділянку пам'яті в системи. Для цього використовується змінна, яка
в бібліотеці мови З називається brk_addr (мал.
4.2, приклад 4.1).

Мал. 4.2. Завантажена програма і brk_addr
Спочатку ця змінна рівна Prog_end
її значення збільшується при виділенні нових блоків, але в деяких випадках
може і зменшуватися. Це відбувається, коли програма визволяє блок,
який закінчується а поточному значенні brkievei.
Приклад 4.1. Виділення додатковій пам'яті в GNU
LIBC для Linux
morecore.с:
/* Copyright (С) 1991, 1992 Free Software Foundation, Inc.
Цей файл є частиною бібліотеки З проекту GNU (GNU З Library).
GNU З Library є вільним програмним забезпеченням;
ви можете передавати її і модифікувати її у відповідності
з положеннями GNU General Public License версії 2 або (по вашому вибору)
'
будь-якій пізнішій версії.
Бібліотека GNU З поширюється в надії, що вона буде корисна, але
БЕЗ ЯКИХ-НЕБУДЬ ГАРАНТІЙ; навіть без неявно передбачуваних гарантій
КОМЕРЦІЙНІЙ
ЦІННОСТІ або ПРИДАТНОСТІ ДЛЯ КОНКРЕТНОЇ МЕТИ. Детальніше за див.
GNU General Public License.
Ви повинні були отримати копію GNU General Public License
GNU З Library; див. файл COPYING. Якщо ви її не отримали, напишіть по
адресі: Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
tifndef _malloc_internal tfdefine _malloc_internal tinclude <malloc.h>
#include <stdlib.h> ttinclude <stdio.h>
#include <errno.h> tinclude <sys/syscall.h> tendif
#ifndef _gnu_library_
tfdefine __sbrk sbrk
#endif
extern void * ___brk_addr;
extern ptr t sbrk P ((int increment));
int _ initbrk Р ( (void) ) ;
fifndef NULL fdefine NULL 0 fendif
/* Виділити ще INCREMENT байтів простору даних
і повернути початок простору даних або NULL при помилках. Якщо INCREMENT
негативний, стискувати простір даних. */
__ptr_t
default_morecore (ptrdiff_t increment)
{
ptr_t result = _ sbrk ((int) increment);
if (result == ( _ ptr_t) -1)
return NULL; return result;
/*
Ця функція майже повністю аналогічна _ def ault_morecore ( ) * Але вона
викликається лише одного дня через morecore.
*/
_ ptr_t
_ default_morecore_init (ptrdiff_t increment)
{
_ ptr_t result;
if ( _ init_brk() != 0)
return NULL;
if ( _ morecore == _ default_morecore_init)
_mprecore = _ default_morecore;
result = _ sbrk ((int) increment);
if (result == ( _ ptr_t) -1)
return NULL;
return result;
}
|