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:
parent
70b3438293
commit
929ec2412f
@ -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);
|
||||||
|
@ -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;
|
||||||
|
36
C/threads.c
36
C/threads.c
@ -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;
|
||||||
|
3
H/Heap.h
3
H/Heap.h
@ -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;
|
||||||
|
3
H/Yap.h
3
H/Yap.h
@ -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,
|
||||||
|
@ -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)) -->
|
||||||
|
@ -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) :-
|
||||||
|
Reference in New Issue
Block a user