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: *
|
||||
* mods: *
|
||||
* 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
|
||||
static char SccsId[] = "%W% %G%";
|
||||
@ -233,7 +233,10 @@ InitExStacks(int Trail, int Stack)
|
||||
* requested */
|
||||
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_LocalBase = Yap_GlobalBase + sa;
|
||||
Yap_TrailBase = Yap_LocalBase + sizeof(CELL);
|
||||
|
@ -10,8 +10,11 @@
|
||||
* File: c_interface.c *
|
||||
* 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 $
|
||||
* Revision 1.109 2008/04/01 15:31:41 vsc
|
||||
* more saved state fixes
|
||||
*
|
||||
* Revision 1.108 2008/03/22 23:35:00 vsc
|
||||
* fix bug in all_calls
|
||||
*
|
||||
@ -1689,6 +1692,17 @@ YAP_Init(YAP_init_args *yap_init)
|
||||
yap_init->SchedulerLoop,
|
||||
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);
|
||||
if (yap_init->QuietMode) {
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
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].tsize = tsize;
|
||||
pm = (ssize + tsize)*1024;
|
||||
if (!(ThreadHandle[new_worker_id].stack_address = malloc(pm))) {
|
||||
return FALSE;
|
||||
}
|
||||
ThreadHandle[new_worker_id].tgoal =
|
||||
Yap_StoreTermInDB(tgoal,4);
|
||||
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 =
|
||||
tdetach;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -190,27 +200,36 @@ p_thread_new_tid(void)
|
||||
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)
|
||||
{
|
||||
store_specs(new_worker_id, ssize, tsize, tgoal, tdetach);
|
||||
return store_specs(new_worker_id, ssize, tsize, tgoal, tdetach);
|
||||
}
|
||||
|
||||
static Int
|
||||
p_create_thread(void)
|
||||
{
|
||||
UInt ssize = IntegerOfTerm(Deref(ARG2));
|
||||
UInt tsize = IntegerOfTerm(Deref(ARG3));
|
||||
/* UInt systemsize = IntegerOfTerm(Deref(ARG4)); */
|
||||
UInt ssize;
|
||||
UInt tsize;
|
||||
Term tgoal = Deref(ARG1);
|
||||
Term tdetach = Deref(ARG5);
|
||||
Term x2 = Deref(ARG2);
|
||||
Term x3 = Deref(ARG3);
|
||||
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) {
|
||||
/* YAP ERROR */
|
||||
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].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) {
|
||||
@ -298,7 +317,8 @@ Yap_thread_create_engine(thread_attr *ops)
|
||||
/* YAP ERROR */
|
||||
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].handle = pthread_self();
|
||||
ThreadHandle[new_id].ref_count = 0;
|
||||
|
3
H/Heap.h
3
H/Heap.h
@ -10,7 +10,7 @@
|
||||
* File: Heap.h *
|
||||
* mods: *
|
||||
* 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 */
|
||||
@ -185,6 +185,7 @@ typedef struct thandle {
|
||||
int zombie;
|
||||
UInt ssize;
|
||||
UInt tsize;
|
||||
void *stack_address;
|
||||
Term tdetach;
|
||||
Term cmod;
|
||||
struct DB_TERM *tgoal;
|
||||
|
3
H/Yap.h
3
H/Yap.h
@ -10,7 +10,7 @@
|
||||
* File: Yap.h.m4 *
|
||||
* mods: *
|
||||
* 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"
|
||||
@ -479,6 +479,7 @@ typedef enum
|
||||
REPRESENTATION_ERROR_CHARACTER_CODE,
|
||||
REPRESENTATION_ERROR_MAX_ARITY,
|
||||
RESOURCE_ERROR_MAX_THREADS,
|
||||
RESOURCE_ERROR_MEMORY,
|
||||
RETRY_COUNTER_UNDERFLOW,
|
||||
SYNTAX_ERROR,
|
||||
SYSTEM_ERROR,
|
||||
|
@ -11,7 +11,7 @@
|
||||
* File: utilities for displaying messages in 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] ].
|
||||
system_message(error(resource_error(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), _)) -->
|
||||
[ 'SYNTAX ERROR: ~a' - [G,Msg] ].
|
||||
system_message(error(syntax_error(_,_,_,Term,Pos,Start), Where)) -->
|
||||
|
@ -63,7 +63,12 @@
|
||||
'$run_at_thread_exit'(Id0),
|
||||
( Detached == true ->
|
||||
'$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) :-
|
||||
@ -74,7 +79,13 @@ thread_create(Goal) :-
|
||||
'$erase_thread_info'(Id),
|
||||
'$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit),
|
||||
'$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) :-
|
||||
G0 = thread_create(Goal, Id),
|
||||
@ -85,7 +96,13 @@ thread_create(Goal, OutId) :-
|
||||
'$erase_thread_info'(Id),
|
||||
'$record_thread_info'(Id, [Stack, Trail, System], Detached, AtExit),
|
||||
'$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.
|
||||
|
||||
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)
|
||||
),
|
||||
'$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.
|
||||
|
||||
'$erase_thread_info'(Id) :-
|
||||
|
Reference in New Issue
Block a user