handle out of memory error at thread creation (obs from Paulo Moura).

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2190 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2008-04-02 17:37:07 +00:00
parent 70b3438293
commit 929ec2412f
7 changed files with 82 additions and 18 deletions

View File

@ -12,7 +12,7 @@
* Last rev: * * Last rev: *
* mods: * * mods: *
* comments: allocating space * * comments: allocating space *
* version:$Id: alloc.c,v 1.91 2008-04-01 22:28:41 vsc Exp $ * * version:$Id: alloc.c,v 1.92 2008-04-02 17:37:05 vsc Exp $ *
*************************************************************************/ *************************************************************************/
#ifdef SCCS #ifdef SCCS
static char SccsId[] = "%W% %G%"; static char SccsId[] = "%W% %G%";
@ -233,7 +233,10 @@ InitExStacks(int Trail, int Stack)
* requested */ * requested */
sa = Stack*K; /* stack area size */ sa = Stack*K; /* stack area size */
Yap_GlobalBase = malloc(pm); #ifdef THREADS
if (worker_id)
Yap_GlobalBase = (ADDR)ThreadHandle[worker_id].stack_address;
#endif
Yap_TrailTop = Yap_GlobalBase + pm; Yap_TrailTop = Yap_GlobalBase + pm;
Yap_LocalBase = Yap_GlobalBase + sa; Yap_LocalBase = Yap_GlobalBase + sa;
Yap_TrailBase = Yap_LocalBase + sizeof(CELL); Yap_TrailBase = Yap_LocalBase + sizeof(CELL);

View File

@ -10,8 +10,11 @@
* File: c_interface.c * * File: c_interface.c *
* comments: c_interface primitives definition * * comments: c_interface primitives definition *
* * * *
* Last rev: $Date: 2008-04-01 15:31:41 $,$Author: vsc $ * * Last rev: $Date: 2008-04-02 17:37:06 $,$Author: vsc $ *
* $Log: not supported by cvs2svn $ * $Log: not supported by cvs2svn $
* Revision 1.109 2008/04/01 15:31:41 vsc
* more saved state fixes
*
* Revision 1.108 2008/03/22 23:35:00 vsc * Revision 1.108 2008/03/22 23:35:00 vsc
* fix bug in all_calls * fix bug in all_calls
* *
@ -1689,6 +1692,17 @@ YAP_Init(YAP_init_args *yap_init)
yap_init->SchedulerLoop, yap_init->SchedulerLoop,
yap_init->DelayedReleaseLoad yap_init->DelayedReleaseLoad
); );
#if USE_SYSTEM_MALLOC
if (Trail < MinTrailSpace)
Trail = MinTrailSpace;
if (Stack < MinStackSpace)
Stack = MinStackSpace;
if (!(Yap_GlobalBase = (ADDR)malloc((Trail+Stack)*1024))) {
yap_init->ErrorNo = RESOURCE_ERROR_MEMORY;
yap_init->ErrorCause = "could not allocate stack space for main thread";
return YAP_BOOT_FROM_SAVED_ERROR;;
}
#endif
Yap_InitExStacks (Trail, Stack); Yap_InitExStacks (Trail, Stack);
if (yap_init->QuietMode) { if (yap_init->QuietMode) {
yap_flags[QUIET_MODE_FLAG] = TRUE; yap_flags[QUIET_MODE_FLAG] = TRUE;

View File

@ -57,11 +57,20 @@ allocate_new_tid(void)
return new_worker_id; return new_worker_id;
} }
static void static int
store_specs(int new_worker_id, UInt ssize, UInt tsize, Term tgoal, Term tdetach) store_specs(int new_worker_id, UInt ssize, UInt tsize, Term tgoal, Term tdetach)
{ {
UInt pm; /* memory to be requested */
if (tsize < MinTrailSpace)
tsize = MinTrailSpace;
if (ssize < MinStackSpace)
ssize = MinStackSpace;
ThreadHandle[new_worker_id].ssize = ssize; ThreadHandle[new_worker_id].ssize = ssize;
ThreadHandle[new_worker_id].tsize = tsize; ThreadHandle[new_worker_id].tsize = tsize;
pm = (ssize + tsize)*1024;
if (!(ThreadHandle[new_worker_id].stack_address = malloc(pm))) {
return FALSE;
}
ThreadHandle[new_worker_id].tgoal = ThreadHandle[new_worker_id].tgoal =
Yap_StoreTermInDB(tgoal,4); Yap_StoreTermInDB(tgoal,4);
ThreadHandle[new_worker_id].cmod = ThreadHandle[new_worker_id].cmod =
@ -73,6 +82,7 @@ store_specs(int new_worker_id, UInt ssize, UInt tsize, Term tgoal, Term tdetach)
ThreadHandle[new_worker_id].tdetach = ThreadHandle[new_worker_id].tdetach =
tdetach; tdetach;
} }
return TRUE;
} }
@ -190,27 +200,36 @@ p_thread_new_tid(void)
return Yap_unify(MkIntegerTerm(new_worker), ARG1); return Yap_unify(MkIntegerTerm(new_worker), ARG1);
} }
static void static int
init_thread_engine(int new_worker_id, UInt ssize, UInt tsize, Term tgoal, Term tdetach) init_thread_engine(int new_worker_id, UInt ssize, UInt tsize, Term tgoal, Term tdetach)
{ {
store_specs(new_worker_id, ssize, tsize, tgoal, tdetach); return store_specs(new_worker_id, ssize, tsize, tgoal, tdetach);
} }
static Int static Int
p_create_thread(void) p_create_thread(void)
{ {
UInt ssize = IntegerOfTerm(Deref(ARG2)); UInt ssize;
UInt tsize = IntegerOfTerm(Deref(ARG3)); UInt tsize;
/* UInt systemsize = IntegerOfTerm(Deref(ARG4)); */
Term tgoal = Deref(ARG1); Term tgoal = Deref(ARG1);
Term tdetach = Deref(ARG5); Term tdetach = Deref(ARG5);
Term x2 = Deref(ARG2);
Term x3 = Deref(ARG3);
int new_worker_id = IntegerOfTerm(Deref(ARG6)); int new_worker_id = IntegerOfTerm(Deref(ARG6));
if (IsBigIntTerm(x2))
return FALSE;
if (IsBigIntTerm(x3))
return FALSE;
ssize = IntegerOfTerm(x2);
tsize = IntegerOfTerm(x3);
/* UInt systemsize = IntegerOfTerm(Deref(ARG4)); */
if (new_worker_id == -1) { if (new_worker_id == -1) {
/* YAP ERROR */ /* YAP ERROR */
return FALSE; return FALSE;
} }
init_thread_engine(new_worker_id, ssize, tsize, tgoal, tdetach); if (!init_thread_engine(new_worker_id, ssize, tsize, tgoal, tdetach))
return FALSE;
ThreadHandle[new_worker_id].id = new_worker_id; ThreadHandle[new_worker_id].id = new_worker_id;
ThreadHandle[new_worker_id].ref_count = 1; ThreadHandle[new_worker_id].ref_count = 1;
if ((ThreadHandle[new_worker_id].ret = pthread_create(&ThreadHandle[new_worker_id].handle, NULL, thread_run, (void *)(&(ThreadHandle[new_worker_id].id)))) == 0) { if ((ThreadHandle[new_worker_id].ret = pthread_create(&ThreadHandle[new_worker_id].handle, NULL, thread_run, (void *)(&(ThreadHandle[new_worker_id].id)))) == 0) {
@ -298,7 +317,8 @@ Yap_thread_create_engine(thread_attr *ops)
/* YAP ERROR */ /* YAP ERROR */
return FALSE; return FALSE;
} }
init_thread_engine(new_id, ops->ssize, ops->tsize, TermNil, TermNil); if (!init_thread_engine(new_id, ops->ssize, ops->tsize, TermNil, TermNil))
return FALSE;
ThreadHandle[new_id].id = new_id; ThreadHandle[new_id].id = new_id;
ThreadHandle[new_id].handle = pthread_self(); ThreadHandle[new_id].handle = pthread_self();
ThreadHandle[new_id].ref_count = 0; ThreadHandle[new_id].ref_count = 0;

View File

@ -10,7 +10,7 @@
* File: Heap.h * * File: Heap.h *
* mods: * * mods: *
* comments: Heap Init Structure * * comments: Heap Init Structure *
* version: $Id: Heap.h,v 1.129 2008-04-02 15:41:50 vsc Exp $ * * version: $Id: Heap.h,v 1.130 2008-04-02 17:37:06 vsc Exp $ *
*************************************************************************/ *************************************************************************/
/* information that can be stored in Code Space */ /* information that can be stored in Code Space */
@ -185,6 +185,7 @@ typedef struct thandle {
int zombie; int zombie;
UInt ssize; UInt ssize;
UInt tsize; UInt tsize;
void *stack_address;
Term tdetach; Term tdetach;
Term cmod; Term cmod;
struct DB_TERM *tgoal; struct DB_TERM *tgoal;

View File

@ -10,7 +10,7 @@
* File: Yap.h.m4 * * File: Yap.h.m4 *
* mods: * * mods: *
* comments: main header file for YAP * * comments: main header file for YAP *
* version: $Id: Yap.h,v 1.32 2008-04-02 15:41:50 vsc Exp $ * * version: $Id: Yap.h,v 1.33 2008-04-02 17:37:06 vsc Exp $ *
*************************************************************************/ *************************************************************************/
#include "config.h" #include "config.h"
@ -479,6 +479,7 @@ typedef enum
REPRESENTATION_ERROR_CHARACTER_CODE, REPRESENTATION_ERROR_CHARACTER_CODE,
REPRESENTATION_ERROR_MAX_ARITY, REPRESENTATION_ERROR_MAX_ARITY,
RESOURCE_ERROR_MAX_THREADS, RESOURCE_ERROR_MAX_THREADS,
RESOURCE_ERROR_MEMORY,
RETRY_COUNTER_UNDERFLOW, RETRY_COUNTER_UNDERFLOW,
SYNTAX_ERROR, SYNTAX_ERROR,
SYSTEM_ERROR, SYSTEM_ERROR,

View File

@ -11,7 +11,7 @@
* File: utilities for displaying messages in YAP. * * File: utilities for displaying messages in YAP. *
* comments: error messages for YAP * * comments: error messages for YAP *
* * * *
* Last rev: $Date: 2008-03-27 00:41:33 $,$Author: vsc $ * * Last rev: $Date: 2008-04-02 17:37:07 $,$Author: vsc $ *
* * * *
* * * *
*************************************************************************/ *************************************************************************/
@ -241,6 +241,8 @@ system_message(error(representation_error(max_arity), Where)) -->
[ 'REPRESENTATION ERROR- ~w: number too big' - [Where] ]. [ 'REPRESENTATION ERROR- ~w: number too big' - [Where] ].
system_message(error(resource_error(threads), Where)) --> system_message(error(resource_error(threads), Where)) -->
[ 'RESOURCE ERROR- too many open threads' - [Where] ]. [ 'RESOURCE ERROR- too many open threads' - [Where] ].
system_message(error(resource_error(memory), Where)) -->
[ 'RESOURCE ERROR- not enough virtual memory' - [Where] ].
system_message(error(syntax_error(G,0,Msg,[],0,0), _)) --> system_message(error(syntax_error(G,0,Msg,[],0,0), _)) -->
[ 'SYNTAX ERROR: ~a' - [G,Msg] ]. [ 'SYNTAX ERROR: ~a' - [G,Msg] ].
system_message(error(syntax_error(_,_,_,Term,Pos,Start), Where)) --> system_message(error(syntax_error(_,_,_,Term,Pos,Start), Where)) -->

View File

@ -63,7 +63,12 @@
'$run_at_thread_exit'(Id0), '$run_at_thread_exit'(Id0),
( Detached == true -> ( Detached == true ->
'$erase_thread_info'(Id0) '$erase_thread_info'(Id0)
; recorda('$thread_exit_status', [Id0|exception(Exception)], _) ;
(
recorded('$thread_exit_status',[Id|_],R), erase(R), fail
;
recorda('$thread_exit_status', [Id|exception(error(resource_error(memory),thread_create(Goal,Id)))])
)
). ).
thread_create(Goal) :- thread_create(Goal) :-
@ -74,7 +79,13 @@ thread_create(Goal) :-
'$erase_thread_info'(Id), '$erase_thread_info'(Id),
'$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit), '$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit),
'$create_thread_mq'(Id), '$create_thread_mq'(Id),
'$create_thread'(Goal, Stack, Trail, System, Detached, Id). (
'$create_thread'(Goal, Stack, Trail, System, Detached, Id)
->
true
;
recorda('$thread_exit_status', [Id|exception(error(resource_error(memory),thread_create(Goal,Id)))],_)
).
thread_create(Goal, OutId) :- thread_create(Goal, OutId) :-
G0 = thread_create(Goal, Id), G0 = thread_create(Goal, Id),
@ -85,7 +96,13 @@ thread_create(Goal, OutId) :-
'$erase_thread_info'(Id), '$erase_thread_info'(Id),
'$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit), '$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit),
'$create_thread_mq'(Id), '$create_thread_mq'(Id),
'$create_thread'(Goal, Stack, Trail, System, Detached, Id), (
'$create_thread'(Goal, Stack, Trail, System, Detached, Id)
->
true
;
recorda('$thread_exit_status', [Id|exception(error(resource_error(memory),thread_create(Goal,Id)))],_)
),
OutId = Id. OutId = Id.
thread_create(Goal, OutId, Options) :- thread_create(Goal, OutId, Options) :-
@ -100,7 +117,13 @@ thread_create(Goal, OutId, Options) :-
; '$record_thread_info'(Id, Alias, [Stack, Trail, System], Detached, AtExit, G0) ; '$record_thread_info'(Id, Alias, [Stack, Trail, System], Detached, AtExit, G0)
), ),
'$create_thread_mq'(Id), '$create_thread_mq'(Id),
'$create_thread'(Goal, Stack, Trail, System, Detached, Id), (
'$create_thread'(Goal, Stack, Trail, System, Detached, Id)
->
true
;
recorda('$thread_exit_status', [Id|exception(error(resource_error(memory),thread_create(Goal,Id,Options)))],_)
),
OutId = Id. OutId = Id.
'$erase_thread_info'(Id) :- '$erase_thread_info'(Id) :-