generic-morestack.c (__splitstack_find): Check for NULL old stack value.

* generic-morestack.c (__splitstack_find): Check for NULL old
	stack value.
	(__splitstack_resetcontext): New function.
	(__splitstack_releasecontext): New function.
	* libgcc-std.ver.in: Add new functions to GCC_4.7.0.

From-SVN: r181771
This commit is contained in:
Ian Lance Taylor 2011-11-28 05:44:31 +00:00 committed by Ian Lance Taylor
parent 8ce3007a90
commit a01207c473
3 changed files with 83 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2011-11-27 Ian Lance Taylor <iant@google.com>
* generic-morestack.c (__splitstack_find): Check for NULL old
stack value.
(__splitstack_resetcontext): New function.
(__splitstack_releasecontext): New function.
* libgcc-std.ver.in: Add new functions to GCC_4.7.0.
2011-11-27 Iain Sandoe <iains@gcc.gnu.org>
* config/darwin-crt-tm.c: Correct comments, use correct licence.

View File

@ -115,6 +115,14 @@ extern void *
__splitstack_makecontext (size_t, void *context[10], size_t *)
__attribute__ ((visibility ("default")));
extern void *
__splitstack_resetcontext (void *context[10], size_t *)
__attribute__ ((visibility ("default")));
extern void
__splitstack_releasecontext (void *context[10])
__attribute__ ((visibility ("default")));
extern void
__splitstack_block_signals_context (void *context[10], int *, int *)
__attribute__ ((visibility ("default")));
@ -911,15 +919,23 @@ __splitstack_find (void *segment_arg, void *sp, size_t *len,
nsp = (char *) segment->old_stack;
if (nsp == NULL)
{
/* We've reached the top of the stack. */
*next_segment = (void *) (uintptr_type) 2;
}
else
{
#if defined (__x86_64__)
nsp -= 12 * sizeof (void *);
nsp -= 12 * sizeof (void *);
#elif defined (__i386__)
nsp -= 6 * sizeof (void *);
nsp -= 6 * sizeof (void *);
#else
#error "unrecognized target"
#endif
*next_sp = (void *) nsp;
*next_sp = (void *) nsp;
}
#ifdef STACK_GROWS_DOWNWARD
*len = (char *) (segment + 1) + segment->size - (char *) sp;
@ -1037,6 +1053,60 @@ __splitstack_makecontext (size_t stack_size, void *context[NUMBER_OFFSETS],
return (void *) (segment + 1);
}
/* Given an existing split stack context, reset it back to the start
of the stack. Return the stack pointer and size, appropriate for
use with makecontext. This may be used if a coroutine exits, in
order to reuse the stack segments for a new coroutine. */
void *
__splitstack_resetcontext (void *context[10], size_t *size)
{
struct stack_segment *segment;
void *initial_sp;
size_t initial_size;
void *ret;
/* Reset the context assuming that MORESTACK_SEGMENTS, INITIAL_SP
and INITIAL_SP_LEN are correct. */
segment = context[MORESTACK_SEGMENTS];
context[CURRENT_SEGMENT] = segment;
context[CURRENT_STACK] = NULL;
if (segment == NULL)
{
initial_sp = context[INITIAL_SP];
initial_size = (uintptr_type) context[INITIAL_SP_LEN];
ret = initial_sp;
#ifdef STACK_GROWS_DOWNWARD
ret = (void *) ((char *) ret - initial_size);
#endif
}
else
{
#ifdef STACK_GROWS_DOWNWARD
initial_sp = (void *) ((char *) (segment + 1) + segment->size);
#else
initial_sp = (void *) (segment + 1);
#endif
initial_size = segment->size;
ret = (void *) (segment + 1);
}
context[STACK_GUARD] = __morestack_make_guard (initial_sp, initial_size);
context[BLOCK_SIGNALS] = NULL;
*size = initial_size;
return ret;
}
/* Release all the memory associated with a splitstack context. This
may be used if a coroutine exits and the associated stack should be
freed. */
void
__splitstack_releasecontext (void *context[10])
{
__morestack_release_segments (context[MORESTACK_SEGMENTS], 1);
}
/* Like __splitstack_block_signals, but operating on CONTEXT, rather
than on the current state. */

View File

@ -1932,4 +1932,6 @@ GCC_4.7.0 {
__splitstack_makecontext
__splitstack_block_signals_context
__splitstack_find_context
__splitstack_resetcontext
__splitstack_releasecontext
}