Общая память BSR
Регистр синхронизации границ (BSR) - это аппаратное обеспечение, которое эффективно обеспечивает совместный доступ к небольшим или сжатым областям памяти. Области памяти обновляются одновременно в несколько потоков.
Память BSR обеспечивает сохраненным блокам памяти более быструю передачу в системе, чем обычная кэш-память. Память BSR использует семантику управления кэш-памятью, которая выделена для манипулирования небольшими блоками памяти от нескольких процессоров в параллельных вычислениях. Семантика управления кэш-памятью изначально не предназначалась для управления разделяемой памятью, но этот механизм полезен для эффективной реализации схемы синхронизации границ, которая используется в высокопроизводительных параллельных потоках.
Для памяти BSR требуется поддержка процессора, и ресурсы логического раздела (LPAR) должны быть настроены на использование функции BSR.
- Выделить общую память V для областей общей памяти системы BSR с помощью функции
shmctl(). - Включить резервное копирование выделенных областей общей системной памяти V в память BSR, для чего вызвать функцию
shmctl()и выполнить команду SHM_BSR.Прим.: В общей памяти используется функцияshmctl()с командой SHM_BSR. Этот шаг выполняется непосредственно после создания резервной копии с помощью функцииshmget()и до того, как первый процесс будет добавлен в общую память. С помощью команды SHM_BSR функцияshmctl()пытается использовать память BSR для заданной области общей памяти. - При недостатке памяти BSR и в том случае, если функции BSR не поддерживаются аппаратной платформой, выводится сообщение об ошибке. Функция
shmget()завершается сerrno, установленным вENOMEMПрим.: Пользователь, не имеющий прав доступа root, должен иметь разрешениеCAP_BYPASS_RAC_VMMдля выделения памяти BSR. В противном случае функцияshmctl()с командой SHM_BSR завершится сerrno, установленным вEPERM.
При использовании общей памяти BSR, в области общей памяти разрешаются только 1-байтовые и 2-байтовые команды хранилища. Команды хранилища, длина которых превышает 2 байта, не работают правильно с общей памятью BSR. Команды загрузки любого размера разрешаются для разделяемой памяти BSR.
Команда VMINFO функции vmgetinfo() используется для сбора сведений об имеющейся поддержке BSR.
При указании команды VMINFO в функции vmgetinfo() возвращается структура vminfo. В поле bsr_mem_total указан общий объем памяти, настроенный LPAR. В поле bsr_mem_free указан общий объем BSR, который в настоящее время доступен для выделения.
Области общей памяти BSR не изменяются динамически с помощью опции SHM_SIZE функции shmctl().
При попытке изменения размера области общей памяти BSR путем указания параметра SHM_SIZE в функции shmctl() функция shmctl() завершается с errno, установленным в EINVAL. Общая память BSR не поддерживается с переменной среды EXTSHM. В том случае если переменная среды EXTSHM задана, при вызовеshmctl() с флагом SHM_BSR функция shmctl() завершается с EINVAL.
Пример
#include <errno.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/vminfo.h>
/* shm_rgn_size - размер области общей памяти область для выделения.
* В этом примере выбрано - 4 КБ (PAGESIZE). 4 КБ - наименьший поддерживаемый
* размер области общей памяти. Ожидается, что 4 КБ должно быть достаточно для
* большинства пользователей.
*/
const size_t shm_rgn_size = PAGESIZE;
int main(int argc, char *argv[])
{
struct vminfo my_info = { 0 };
int id;
void *ptr;
/* Определяется объем доступной памяти BSR */
if (vmgetinfo(&my_info, VMINFO, sizeof(my_info)) != 0)
{
perror("неожиданный сбой vmgetinfo()");
return 1;
}
/* Проверка, что имеется достаточно памяти BSR */
if (my_info.bsr_mem_free < shm_rgn_size)
{
fprintf(stderr, "недостаточно памяти BSR\n");
return 2;
}
/* Выделяется новая область общей памяти */
id = shmget(IPC_PRIVATE, shm_rgn_size, IPC_CREAT|IPC_EXCL);
if (id == -1)
{
perror("не удалось выполнить shmget()");
return 3;
}
/* Запрос памяти BSR для области общей памяти */
if (shmctl(id, SHM_BSR, NULL))
{
perror("не удалось выполнить shmctl(SHM_BSR)");
shmctl(id, IPC_RMID, 0);
return 4;
}
/* Присоединение области общей памяти */
ptr = shmat(id, NULL, 0);
if ((int)ptr == -1)
{
perror("не удалось выполнить shmat()");
shmctl(id, IPC_RMID, 0);
return 5;
}
/* BSR память может быть доступна, начиная с адреса - ptr */
/* Отсоединение области общей памяти */
if (shmdt(ptr))
{
perror("не удалось выполнить shmdt()");
shmctl(id, IPC_RMID, 0);
return 6;
}
/* Удаление области общей памяти */
if (shmctl(id, IPC_RMID, 0))
{
perror("не удалось выполнить shmctl(IPC_RMID)");
return 7;
}
return 0;
}