Я прочитал программу, в которой используется DIRECT_IO, чтобы вставить ОДИН регистр (prof struct). Мое сомнение в том, что я правильно использую posix_memalign здесь. Я знаю, что выделенный блок памяти должен быть выровнен, чтобы использовать подход DIRECT_IO.В чем смысл posix_memalign в этой программе?
Моя программа (которая работает, но, пожалуйста, дайте мне знать, какие-либо предложения):
#define _GNU_SOURCE /* for O_DIRECT */
#include <stdio.h>
#include <sys/types.h> /* required by open() */
#include <unistd.h> /* open(), write() */
#include <fcntl.h> /* open() and fcntl() */
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
#define PAGE_SIZE 4096
#define LENGTH 50
typedef struct {
int nusp;
char first_name[LENGTH];
char last_name[LENGTH];
char department[LENGTH];
int year_of_begin;
} prof;
int disk_open() {
int flag;
int ret;
flag = O_CREAT | O_RDWR | O_DIRECT;
if ((ret = open("test.header", flag, S_IRUSR | S_IWUSR)) < 0) {
printf("was impossible to create the file");
return -1;
}
return ret;
}
int main() {
int cmd;
prof d;
int arq;
uint8_t *buf, *loc;
size_t bufsize;
do {
printf("Digite:\n");
printf("****\n(1) insert\n(2) see register\n(3) leave\n****\n");
scanf("%d", &cmd);
switch (cmd) {
case 1:
printf("ID: ");
scanf("%d", &(d.nusp));
printf("NAME: ");
scanf("%s", (d.first_name));
printf("LASTNAME: ");
scanf("%s", (d.last_name));
printf("DEPARTAMENT: ");
scanf("%s", (d.department));
printf("YEAR: ");
scanf("%d", &(d.year_of_begin));
bufsize = sizeof (int) +
sizeof (d.first_name) +
sizeof (d.last_name) +
sizeof (d.department) +
sizeof (int);
printf("bufsize = %d\n", bufsize);
//buf = (uint8_t*) malloc(bufsize);
if(posix_memalign((void**)&buf, PAGE_SIZE, bufsize)) {
printf("allocation failed\n");
}
loc = buf;
memcpy(loc, &(d.nusp), sizeof (int));
loc += sizeof (int);
memcpy(loc, d.first_name, sizeof (d.first_name));
loc += sizeof (d.first_name);
memcpy(loc, d.last_name, sizeof (d.first_name));
loc += sizeof (d.last_name);
memcpy(loc, d.department, sizeof (d.department));
loc += sizeof (d.department);
memcpy(loc, &(d.year_of_begin), sizeof (int));
loc += sizeof (int);
arq = disk_open();
printf("bytes written: %d\n", write(arq, buf, PAGE_SIZE));
free(buf);
close(arq);
break;
case 2:
arq = disk_open();
bufsize = sizeof (int) +
sizeof (d.first_name) +
sizeof (d.last_name) +
sizeof (d.department) +
sizeof (int);
//buf = (uint8_t*) malloc(bufsize);
posix_memalign((void**)&buf, PAGE_SIZE, bufsize);
printf("read %d bytes\n", read(arq, buf, PAGE_SIZE));
memcpy(&(d.nusp), buf, sizeof (int));
buf += sizeof (int);
memcpy(d.first_name, buf, sizeof (d.first_name));
buf += sizeof (d.first_name);
memcpy(d.last_name, buf, sizeof (d.last_name));
buf += sizeof (d.last_name);
memcpy(d.department, buf, sizeof (d.department));
buf += sizeof (d.department);
memcpy(&(d.year_of_begin), buf, sizeof (int));
buf += sizeof (int);
printf("ID: %d\n", d.nusp);
printf("NAME: %s\n", d.first_name);
printf("LAST NAME: %s\n", d.last_name);
printf("DEPARTAMENT: %s\n", d.department);
printf("YEAR: %d\n", d.year_of_begin);
printf("\n");
close(arq);
break;
default:
printf("Leaving....");
break;
}
} while (cmd != 3);
return 0;
}
Итак, мой вопрос: В posix_memalign((void**)&buf, PAGE_SIZE, bufsize);
, я распределение 158 байт в блоке памяти 4096 байты (т. е. размер моей страницы), что означает, что я трачу 3938 байт? Это происходит, так как я должен написать/прочитать выровненную блочную память, которая в этом случае равна 4096 (мощность в два), правильно?
Что произойдет, если мой PAGE_SIZE равен bufsize (учтите, что bufsize и PAGE_SIZE имеют размеры, равные 4096 байтам в этом случае)? Это означает, что я не трачу байты в память и диск?
Если я хочу использовать DIRECT_IO в Windows, возможно ли это? Если да, какую библиотеку/функции я должен использовать для выделения выровненных блоков памяти?
Благодарим вас за разъяснения. Я понял смысл posix_memalign. Теперь, когда вы сказали: «вы не должны пытаться читать или писать в эту память». Если я пытаюсь читать/писать только 158 байтов (как размер) с помощью функций чтения и записи, это дает мне ошибки. Затем из-за этого я использую: write (arq, buf, PAGE_SIZE). Это неправильно? В моем реальном приложении bufsize и PAGE_SIZE будут очень похожи по размеру. –
Вы не должны пытаться читать/писать за пределами выделенной памяти. Если вам нужно читать/записывать в 4K кусках, вам нужно выделить в 4K кусках, даже если ваша структура меньше 4K, и просто согласитесь с тем, что остаток блока памяти/диска будет мусором, и вы теряете память и дисковое пространство. – Petesh