From e22b870b4a4c02f762471744675f5b4d8a940304 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 Mar 2018 14:44:17 +0200 Subject: Cleanup: global undo (minor changes to internals) - Get memory usage from MemFile instead of MEM API avoids possible invalid when threads alloc memory. - Use size_t instead of uint and uintptr_t to store size. - Rename UndoElem.str -> filename - Rename MemFileChunk.ident -> is_identical --- source/blender/blenkernel/intern/blender_undo.c | 32 +++++++++++++------------ source/blender/blenloader/BLO_undofile.h | 11 +++++---- source/blender/blenloader/intern/undofile.c | 26 +++++++++++--------- 3 files changed, 38 insertions(+), 31 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c index e3a5edb2049..4efca5bcc41 100644 --- a/source/blender/blenkernel/intern/blender_undo.c +++ b/source/blender/blenkernel/intern/blender_undo.c @@ -75,10 +75,11 @@ typedef struct UndoElem { struct UndoElem *next, *prev; - char str[FILE_MAX]; + /* Only for 'UNDO_DISK' */ + char filename[FILE_MAX]; char name[BKE_UNDO_STR_MAX]; MemFile memfile; - uintptr_t undosize; + size_t undo_size; } UndoElem; static ListBase undobase = {NULL, NULL}; @@ -107,10 +108,12 @@ static int read_undosave(bContext *C, UndoElem *uel) fileflags = G.fileflags; G.fileflags |= G_FILE_NO_UI; - if (UNDO_DISK) - success = (BKE_blendfile_read(C, uel->str, NULL, 0) != BKE_BLENDFILE_READ_FAIL); - else + if (UNDO_DISK) { + success = (BKE_blendfile_read(C, uel->filename, NULL, 0) != BKE_BLENDFILE_READ_FAIL); + } + else { success = BKE_blendfile_read_from_memfile(C, &uel->memfile, NULL, 0); + } /* restore */ BLI_strncpy(G.main->name, mainstr, sizeof(G.main->name)); /* restore */ @@ -127,7 +130,6 @@ static int read_undosave(bContext *C, UndoElem *uel) /* name can be a dynamic string */ void BKE_undo_write(bContext *C, const char *name) { - uintptr_t maxmem, totmem, memused; int nr /*, success */ /* UNUSED */; UndoElem *uel; @@ -174,40 +176,40 @@ void BKE_undo_write(bContext *C, const char *name) /* disk save version */ if (UNDO_DISK) { static int counter = 0; - char filepath[FILE_MAX]; + char filename[FILE_MAX]; char numstr[32]; int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */ - /* calculate current filepath */ + /* Calculate current filename. */ counter++; counter = counter % U.undosteps; BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); - BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr); + BLI_make_file_string("/", filename, BKE_tempdir_session(), numstr); - /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL); - BLI_strncpy(curundo->str, filepath, sizeof(curundo->str)); + BLI_strncpy(curundo->filename, filename, sizeof(curundo->filename)); } else { MemFile *prevfile = NULL; if (curundo->prev) prevfile = &(curundo->prev->memfile); - memused = MEM_get_memory_in_use(); /* success = */ /* UNUSED */ BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags); - curundo->undosize = MEM_get_memory_in_use() - memused; + curundo->undo_size = curundo->memfile.size; } if (U.undomemory != 0) { + size_t maxmem, totmem; /* limit to maximum memory (afterwards, we can't know in advance) */ totmem = 0; - maxmem = ((uintptr_t)U.undomemory) * 1024 * 1024; + maxmem = ((size_t)U.undomemory) * 1024 * 1024; /* keep at least two (original + other) */ uel = undobase.last; while (uel && uel->prev) { - totmem += uel->undosize; + totmem += uel->undo_size; if (totmem > maxmem) break; uel = uel->prev; } diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h index fb96ec75e62..d3c0130a63b 100644 --- a/source/blender/blenloader/BLO_undofile.h +++ b/source/blender/blenloader/BLO_undofile.h @@ -35,15 +35,16 @@ typedef struct { void *next, *prev; - - char *buf; - unsigned int ident, size; - + const char *buf; + /** Size in bytes. */ + unsigned int size; + /** When true, this chunk doesn't own the memory, it's shared with a previous #MemFileChunk */ + bool is_identical; } MemFileChunk; typedef struct MemFile { ListBase chunks; - unsigned int size; + size_t size; } MemFile; /* actually only used writefile.c */ diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index c191e48a143..ffc7d7c83f5 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -43,6 +43,9 @@ #include "BLO_undofile.h" +/* keep last */ +#include "BLI_strict_flags.h" + /* **************** support for memory-write, for undo buffers *************** */ /* not memfile itself */ @@ -51,8 +54,9 @@ void BLO_memfile_free(MemFile *memfile) MemFileChunk *chunk; while ((chunk = BLI_pophead(&memfile->chunks))) { - if (chunk->ident == 0) - MEM_freeN(chunk->buf); + if (chunk->is_identical == false) { + MEM_freeN((void *)chunk->buf); + } MEM_freeN(chunk); } memfile->size = 0; @@ -68,9 +72,9 @@ void BLO_memfile_merge(MemFile *first, MemFile *second) sc = second->chunks.first; while (fc || sc) { if (fc && sc) { - if (sc->ident) { - sc->ident = 0; - fc->ident = 1; + if (sc->is_identical) { + sc->is_identical = false; + fc->is_identical = true; } } if (fc) fc = fc->next; @@ -98,7 +102,7 @@ void memfile_chunk_add(MemFile *compare, MemFile *current, const char *buf, unsi curchunk = MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk"); curchunk->size = size; curchunk->buf = NULL; - curchunk->ident = 0; + curchunk->is_identical = false; BLI_addtail(¤t->chunks, curchunk); /* we compare compchunk with buf */ @@ -106,17 +110,17 @@ void memfile_chunk_add(MemFile *compare, MemFile *current, const char *buf, unsi if (compchunk->size == curchunk->size) { if (memcmp(compchunk->buf, buf, size) == 0) { curchunk->buf = compchunk->buf; - curchunk->ident = 1; + curchunk->is_identical = true; } } compchunk = compchunk->next; } - + /* not equal... */ if (curchunk->buf == NULL) { - curchunk->buf = MEM_mallocN(size, "Chunk buffer"); - memcpy(curchunk->buf, buf, size); + char *buf_new = MEM_mallocN(size, "Chunk buffer"); + memcpy(buf_new, buf, size); + curchunk->buf = buf_new; current->size += size; } } - -- cgit v1.2.3