The problem still exists as of 0.11pre0-9.1 but I was able to fix it. The patch is attached. It converts the current stack on array with obvious overflow problems to a stack on a circular buffer. So now when the stack is full it just drops the oldest element. Since the stack size is 4096 and it is used to store moves for undo/redo this should not be a problem.
-- Alexander
From 10fe62d7c8065845a19db006ef7a4fded4e5bda1 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev <lasa...@lvk.cs.msu.su> Date: Tue, 20 Oct 2009 03:47:30 +0400 Subject: [PATCH] use cirtcular buffer for stack Signed-off-by: Alexander Gordeev <lasa...@lvk.cs.msu.su> --- src/stack.c | 72 ++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/stack.c b/src/stack.c index 737cd9c..5dcc10d 100644 --- a/src/stack.c +++ b/src/stack.c @@ -34,6 +34,9 @@ movstack_ptr ---> movstack_max : "forward" list */ +//! Start offset of the stack in the circular buffer +static int movstack_start = 0; + //! Current position in the stack static int movstack_ptr = 0; @@ -67,31 +70,38 @@ int movstack_get_num_moves() void movstack_push (byte *board, byte *move) { - assert (movstack_ptr < STACK_SIZE - 1); - movstack[movstack_ptr] = movdup (move); - movinvstack[movstack_ptr] = mov_getinv (board, move); - movstack_ptr++; - if (movstack_ptr > movstack_max) - movstack_max = movstack_ptr; + movstack[(movstack_start + movstack_ptr) % STACK_SIZE] = movdup (move); + movinvstack[(movstack_start + movstack_ptr) % STACK_SIZE] = mov_getinv (board, move); + if (movstack_ptr < STACK_SIZE - 1) { + movstack_ptr++; + if (movstack_ptr > movstack_max) + movstack_max = movstack_ptr; + } else { + free (movstack[movstack_start]); + free (movinvstack[movstack_start]); + movstack_start = (movstack_start + 1) % STACK_SIZE; + } } byte *movstack_pop () { if (movstack_ptr == 0) return NULL; - return movstack[--movstack_ptr]; + movstack_ptr--; + return movstack[(movstack_start + movstack_ptr) % STACK_SIZE]; } -//! Truncates a stack to the current poisition. -/** This will be called when the user makes a move when it is not the final poisition. */ +//! Truncates a stack to the current position. +/** This will be called when the user makes a move when it is not the final position. */ void movstack_trunc () { int i; assert (movstack_ptr <= movstack_max); for (i = movstack_ptr; i < movstack_max; i++) { - free (movstack[i]); - free (movinvstack[i]); + int j = (movstack_start + i) % STACK_SIZE; + free (movstack[j]); + free (movinvstack[j]); } movstack_max = movstack_ptr; } @@ -101,7 +111,7 @@ byte * movstack_forw () if (movstack_ptr < movstack_max) movstack_ptr++; else return NULL; - return movstack[movstack_ptr-1]; + return movstack[(movstack_start + movstack_ptr - 1) % STACK_SIZE]; } byte * movstack_back () @@ -109,7 +119,7 @@ byte * movstack_back () if (movstack_ptr > 0) movstack_ptr--; else return NULL; - return movinvstack[movstack_ptr]; + return movinvstack[(movstack_start + movstack_ptr) % STACK_SIZE]; } void movstack_free () @@ -117,8 +127,9 @@ void movstack_free () int i; for (i=0; i<movstack_max; i++) { - free (movstack[i]); - free (movinvstack[i]); + int j = (movstack_start + i) % STACK_SIZE; + free (movstack[j]); + free (movinvstack[j]); } movstack_max = movstack_ptr = 0; } @@ -128,7 +139,7 @@ void movstack_free () state stack */ -static int statestack_ptr = 0, statestack_max = 0; +static int statestack_start = 0, statestack_ptr = 0, statestack_max = 0; static void *statestack[STACK_SIZE]; @@ -136,28 +147,35 @@ static void *statestack[STACK_SIZE]; void statestack_push (void *state) { void *newstate; - assert (statestack_ptr < STACK_SIZE - 1); newstate = malloc (game_state_size); assert (newstate); memcpy (newstate, state, game_state_size); - statestack[statestack_ptr] = newstate; - statestack_ptr++; - if (statestack_ptr > statestack_max) - statestack_max = statestack_ptr; + + statestack[(statestack_start + statestack_ptr) % STACK_SIZE] = newstate; + + if (statestack_ptr < STACK_SIZE - 1) { + statestack_ptr++; + if (statestack_ptr > statestack_max) + statestack_max = statestack_ptr; + } else { + free (statestack[statestack_start]); + statestack_start = (statestack_start + 1) % STACK_SIZE; + } } void *statestack_peek () { if (statestack_ptr == 0) return NULL; - return statestack[statestack_ptr-1]; + return statestack[(statestack_start + statestack_ptr - 1) % STACK_SIZE]; } void *statestack_pop () { if (statestack_ptr == 0) return NULL; - return statestack[--statestack_ptr]; + statestack_ptr--; + return statestack[(statestack_start + statestack_ptr) % STACK_SIZE]; } void statestack_trunc () @@ -165,7 +183,7 @@ void statestack_trunc () int i; assert (statestack_ptr <= statestack_max); for (i = statestack_ptr; i < statestack_max; i++) - free (statestack[i]); + free (statestack[(statestack_start + i) % STACK_SIZE]); statestack_max = statestack_ptr; } @@ -174,7 +192,7 @@ void * statestack_forw () if (statestack_ptr < statestack_max) statestack_ptr++; else return NULL; - return statestack[statestack_ptr-1]; + return statestack[(statestack_start + statestack_ptr - 1) % STACK_SIZE]; } void * statestack_back () @@ -182,14 +200,14 @@ void * statestack_back () if (statestack_ptr > 0) statestack_ptr--; else return NULL; - return statestack[statestack_ptr-1]; + return statestack[(statestack_start + statestack_ptr - 1) % STACK_SIZE]; } void statestack_free () { int i; for (i=0; i<statestack_max; i++) - free (statestack[i]); + free (statestack[(statestack_start + i) % STACK_SIZE]); statestack_max = statestack_ptr = 0; } -- 1.6.3.3
signature.asc
Description: PGP signature