2005-09-08 23:36:16 +01:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
* *
|
|
|
|
|
* BEAM -> Basic Extended Andorra Model *
|
|
|
|
|
* BEAM extends the YAP Prolog system to support the EAM *
|
|
|
|
|
* Copyright: Ricardo Lopes and NCC - University of Porto, Portugal *
|
|
|
|
|
* *
|
|
|
|
|
**************************************************************************
|
|
|
|
|
* comments: eam abstract machine emulator *
|
|
|
|
|
* *
|
|
|
|
|
* IMPORTANT: ON i386 ISAPPL SHOUD ALWAYS BE AFTER ISVAR *
|
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
|
|
#ifdef BEAM
|
|
|
|
|
|
|
|
|
|
#include "Yap.h"
|
|
|
|
|
#include "Yatom.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2005-10-09 22:13:57 +01:00
|
|
|
|
#define Debug 0
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#define Debug_GC 1
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#define Debug_Dump_State 0 /* 0 =off || 1==only on Scheduling || 2== only on GC || 4=on every abs inst NOTE: DEBUG has to be enable to use 4*/
|
2005-10-09 22:13:57 +01:00
|
|
|
|
#define Debug_MEMORY 0
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#define Memory_Stat 0
|
|
|
|
|
#define Clear_MEMORY 0 /* 0- do not clear || 1-> clear on request || 2-> clear on release || 3 -> both*/
|
|
|
|
|
#define Fast_go 1 /* normaly 1 ; use 0 to run some extra tests only to control some possible bugs (slower) */
|
|
|
|
|
#define USE_SPLIT 1
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#define MEM_FOR_BOXES 32 /* In Mb */
|
|
|
|
|
#define MEM_FOR_HEAP 32 /* In Mb */
|
|
|
|
|
#define MEM_FOR_VARS 32 /* In Mb */
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#define MEM_BOXES MEM_FOR_BOXES*1024*1024
|
|
|
|
|
#define MEM_H MEM_FOR_HEAP*1024*1024
|
|
|
|
|
#define MEM_VARS MEM_FOR_VARS*1024*1024
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#define INDEX_SIZE 100000 /* size of vector for saving memory requests */
|
|
|
|
|
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#define GARBAGE_COLLECTOR 2 /* 0= NO GC || 1 = Heap only || 2 = Heap + Box */
|
|
|
|
|
#define HYBRID_BOXMEM 1 /* 0 - Off || 1 - On */
|
|
|
|
|
#define START_ON_NEXT 1 /* PLEASE DON'T CHANGE , specially if you use skip_while_var */
|
|
|
|
|
#define USE_LEFTMOST 1 /* SHOULD ALWAYS BE 1 for now... */
|
|
|
|
|
#define MICRO_TIME 1 /* 0 == eamtime uses CPU time 1 == eamtime uses total time */
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#define MAX_MEMORYSTAT 5000
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#define READ 0
|
|
|
|
|
#define WRITE 1
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#include "eam.h"
|
|
|
|
|
#include "eamamasm.h"
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
int EAM=0; /* Is EAM enabled ? */
|
|
|
|
|
Cell *beam_ALTERNATIVES; /* NEEDED FOR ABSMI */
|
|
|
|
|
PredEntry *bpEntry;
|
|
|
|
|
struct EAM_Global EAMGlobal;
|
|
|
|
|
struct EAM_Global *eamGlobal=&EAMGlobal;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#if !Debug
|
|
|
|
|
#define INLINE inline
|
|
|
|
|
#define DIRECT_JUMP 1
|
|
|
|
|
#else
|
|
|
|
|
#define INLINE
|
|
|
|
|
#define DIRECT_JUMP 0
|
|
|
|
|
void break_top(void); void break_top(void) { };
|
2006-04-12 18:26:14 +01:00
|
|
|
|
void break_debug(int);
|
|
|
|
|
void break_debug(int conta) {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#if Debug_Dump_State & 4
|
|
|
|
|
dump_eam_state();
|
|
|
|
|
#endif
|
2006-04-12 18:26:14 +01:00
|
|
|
|
if (Debug!=-1 && conta>Debug*100) {printf("exit por contador>debug\n"); exit(1); }
|
2006-03-24 16:19:31 +00:00
|
|
|
|
};
|
|
|
|
|
#endif
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#define push_mode_and_sreg() { *--beam_sp = (Cell) beam_Mode; *--beam_sp = (Cell) beam_S; }
|
|
|
|
|
#define pop_mode_and_sreg() { beam_S = (Cell *) *beam_sp++; beam_Mode = (short) *beam_sp++; }
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
#define isvar(a) IsVarTerm((Cell) a)
|
|
|
|
|
#define isappl(a) IsApplTerm((Cell) a)
|
|
|
|
|
#define ispair(a) IsPairTerm((Cell) a)
|
|
|
|
|
#define isatom(a) IsAtomOrIntTerm((Cell) a)
|
|
|
|
|
#define reppair(a) RepPair((Cell) a)
|
|
|
|
|
#define repappl(a) RepAppl((Cell) a)
|
|
|
|
|
#define abspair(a) AbsPair((Term *) a)
|
|
|
|
|
#define absappl(a) AbsAppl((Term *) a)
|
2006-04-08 15:56:48 +01:00
|
|
|
|
|
|
|
|
|
int is_perm_var(Cell *a); inline int is_perm_var(Cell *a) { if (a>=(Cell *) beam_END_BOX && a<(Cell *) (beam_END_BOX+MEM_VARS)) return(1); else return (0); }
|
|
|
|
|
//int is_perm_var(Cell *a); inline int is_perm_var(Cell *a) { if (a<(Cell *) beam_END_BOX) return(0); else return (1); }
|
|
|
|
|
//int is_perm_var(Cell *a); inline int is_perm_var(Cell *a) { if ( a<(Cell *) beam_START_ADDR_HEAP || a>=(Cell *) beam_END_BOX) return(1); else return (0); }
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
Cell deref(Cell a);
|
|
|
|
|
int Unify(Cell *a, Cell *b);
|
|
|
|
|
void UnifyCells(Cell *a, Cell *b);
|
|
|
|
|
void trail(struct AND_BOX *andbox,struct PERM_VAR *a);
|
|
|
|
|
void limpa_trail(struct AND_BOX *andbox);
|
|
|
|
|
void get_arguments(int nr, Cell *a);
|
|
|
|
|
Cell *save_arguments(int nr);
|
|
|
|
|
void remove_memory_arguments(Cell *a);
|
|
|
|
|
void initialize_memory_areas(void);
|
|
|
|
|
Cell *request_memory(int size);
|
|
|
|
|
void free_memory(Cell *mem,int size);
|
|
|
|
|
void limpa_trail_orbox(struct OR_BOX *orbox);
|
|
|
|
|
struct SUSPENSIONS *addto_suspensions_list(struct AND_BOX *a,int reason);
|
|
|
|
|
void delfrom_suspensions_list(struct SUSPENSIONS *b);
|
|
|
|
|
void totop_suspensions_list(struct SUSPENSIONS *b);
|
|
|
|
|
int verify_externals(struct AND_BOX *and_box);
|
|
|
|
|
void remove_from_perm_var_suspensions(struct PERM_VAR *v,struct AND_BOX *andbox);
|
|
|
|
|
void change_perm_var_suspensions(struct PERM_VAR *v,struct AND_BOX *andbox,struct AND_BOX *new);
|
|
|
|
|
void do_forking_andbox(struct AND_BOX *a);
|
|
|
|
|
void remove_all_externals(struct AND_BOX *andbox);
|
|
|
|
|
void remove_all_externals_suspensions(struct AND_BOX *andbox);
|
|
|
|
|
void del_andbox_and_sons(struct AND_BOX *andbox);
|
|
|
|
|
void del_orbox_and_sons(struct OR_BOX *orbox);
|
|
|
|
|
void waking_boxes_suspended_on_var(struct PERM_VAR *v);
|
|
|
|
|
struct PERM_VAR *request_permVar(struct AND_BOX *a);
|
|
|
|
|
void free_permVar(struct PERM_VAR *v);
|
2005-10-09 22:13:57 +01:00
|
|
|
|
Cell *request_memory_locals(int nr);
|
|
|
|
|
Cell *request_memory_locals_noinit(int nr);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
void free_memory_locals(Cell *l);
|
|
|
|
|
void add_to_list_perms(struct PERM_VAR *var,struct AND_BOX *a);
|
|
|
|
|
void remove_list_perms(struct AND_BOX *a);
|
|
|
|
|
void move_perm_vars(struct AND_BOX *b, struct AND_BOX *a);
|
|
|
|
|
void move_perm_variables(struct AND_BOX *a);
|
|
|
|
|
void inc_level(struct AND_BOX *andbox,int dif);
|
|
|
|
|
void abort_eam(char *s);
|
|
|
|
|
void exit_eam(char *s);
|
|
|
|
|
int HEAP_MEM_FULL(void);
|
|
|
|
|
void change_from_to(struct PERM_VAR *o,struct PERM_VAR *d);
|
|
|
|
|
unsigned int index_of_hash_table_atom(Cell c, int nr);
|
|
|
|
|
unsigned int index_of_hash_table_appl(Cell c, int nr);
|
|
|
|
|
int deve_limpar_var(struct EXTERNAL_VAR *e);
|
|
|
|
|
struct status_and *remove_call_from_andbox(struct status_and *ncall, struct AND_BOX *a);
|
|
|
|
|
int is_leftmost(struct AND_BOX *a, struct status_and *n);
|
|
|
|
|
int exists_var_in(Cell *c);
|
|
|
|
|
void garbage_collector(void);
|
|
|
|
|
void conta_memoria_livre(int size);
|
|
|
|
|
int showTime(void);
|
|
|
|
|
struct AND_BOX *choose_leftmost(void);
|
2006-03-24 16:19:31 +00:00
|
|
|
|
extern Cell BEAM_is(void);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
extern void do_eam_indexing(struct Predicates *);
|
2015-06-17 23:54:54 +01:00
|
|
|
|
extern void Yap_plwrite(Term, struct stream_desc *, int, int);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
#if Debug_Dump_State
|
|
|
|
|
void dump_eam_state(void);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************\
|
|
|
|
|
* Debug + Status routines *
|
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
|
|
void conta_memoria_livre(int size){
|
|
|
|
|
int i,nr,ult=0;
|
|
|
|
|
long total=0;
|
|
|
|
|
Cell *c;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<INDEX_SIZE;i++) {
|
|
|
|
|
nr=0;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
c=beam_IndexFree[i];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
while(c!=NULL) {
|
|
|
|
|
ult=i;
|
|
|
|
|
nr++;
|
|
|
|
|
c=(Cell *) *c;
|
|
|
|
|
}
|
|
|
|
|
total=total+nr*i;
|
|
|
|
|
}
|
2006-04-08 15:56:48 +01:00
|
|
|
|
printf("Ultimo Pedido (bytes) =%d <20> Ultimo bloco livre=%d\n",size,(int) ult*CELL_SIZE);
|
2006-03-24 16:19:31 +00:00
|
|
|
|
printf("Memoria TOTAL (bytes) =%ld \n",((unsigned long) beam_END_BOX)-((unsigned long) beam_START_ADDR_BOXES));
|
|
|
|
|
printf("Memoria livre no IndexFree=%ld \n",total*CELL_SIZE);
|
|
|
|
|
printf("Memoria Total livre =%ld \n",total*CELL_SIZE+((unsigned long) beam_END_BOX)-((unsigned long)beam_NextFree));
|
|
|
|
|
printf("Memoria Total na HEAP=%ld livre=%ld \n",(unsigned long) MEM_H,(unsigned long) beam_H-(unsigned long) beam_START_ADDR_HEAP);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void abort_eam(char *s)
|
|
|
|
|
{
|
|
|
|
|
printf("%s\n",s);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void exit_eam(char *s)
|
|
|
|
|
{
|
|
|
|
|
printf("%s\n",s);
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_nr_call_forking) printf("%d forks executed\n",beam_nr_call_forking);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_nr_gc_heap)
|
|
|
|
|
printf("GC was called %d times on Heap Mem\n",beam_nr_gc_heap);
|
|
|
|
|
if (beam_nr_gc_boxed)
|
|
|
|
|
printf("GC was called %d times on Boxed Mem\n",beam_nr_gc_boxed);
|
|
|
|
|
if (beam_nr_gc_boxed && beam_nr_gc_heap)
|
|
|
|
|
printf("GC was called %d times \n",beam_nr_gc_boxed+beam_nr_gc_heap);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
|
|
|
|
{unsigned long req, used;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
req=beam_TOTAL_MEM+beam_TOTAL_PERMS;
|
|
|
|
|
used=(beam_TOTAL_MEM+beam_TOTAL_PERMS)-(beam_MEM_REUSED+beam_PERMS_REUSED);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
printf("-------------------------------------------------------------------\n");
|
|
|
|
|
printf("Total Mem: Requested %ld (%.2fKb) (%.2fMb) \n", req, req/1024.0, req/1048576.0);
|
|
|
|
|
printf(" Used %ld (%.2fKb) (%.2fMb) / Reused (%3.2f%c)\n", used,used/1024.0, used/1048576.0, (float) (req-used)/req*100,'%');
|
|
|
|
|
printf("-------------------------------------------------------------------\n");
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
used=(beam_TOTAL_MEM-beam_TOTAL_TEMPS)-(beam_MEM_REUSED-beam_TEMPS_REUSED);
|
|
|
|
|
printf("Boxed Mem: Requested %ld (%.2fKb) (%.2fMb) \n", beam_TOTAL_MEM-beam_TOTAL_TEMPS, (beam_TOTAL_MEM-beam_TOTAL_TEMPS)/1024.0, (beam_TOTAL_MEM-beam_TOTAL_TEMPS)/1048576.0);
|
|
|
|
|
printf(" Used %ld (%.2fKb) (%.2fMb) / Reused (%3.2f%c)\n", used, used/1024.0, used/1048576.0, (float) (beam_MEM_REUSED-beam_TEMPS_REUSED)/(beam_TOTAL_MEM-beam_TOTAL_TEMPS)*100,'%');
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
used=beam_TOTAL_TEMPS-beam_TEMPS_REUSED;
|
|
|
|
|
printf("Temps Mem: Requested %ld (%.2fKb) (%.2fMB)\n", beam_TOTAL_TEMPS, beam_TOTAL_TEMPS/1024.0, beam_TOTAL_TEMPS/1048576.0);
|
|
|
|
|
printf(" Used %ld (%.2fKb) (%.2fMb) / Reused (%3.2f%c)\n", used, used/1024.0,used/1048576.0,(float) beam_TEMPS_REUSED/(beam_TOTAL_TEMPS)*100,'%');
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
used=beam_TOTAL_PERMS-beam_PERMS_REUSED;
|
|
|
|
|
printf("Perms Mem: Requested %ld (%.2fKb) (%.2fMB)\n", beam_TOTAL_PERMS, beam_TOTAL_PERMS/1024.0, beam_TOTAL_PERMS/1048576.0);
|
|
|
|
|
printf(" Used %ld (%.2fKb) (%.2fMb) / Reused (%3.2f%c)\n", used, used/1024.0,used/1048576.0,(float) beam_PERMS_REUSED/(beam_TOTAL_PERMS)*100,'%');
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
printf("-------------------------------------------------------------------\n");
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_nr_gc_boxed+beam_nr_gc_heap>0) {
|
2005-09-08 23:36:16 +01:00
|
|
|
|
int i;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_Memory_STAT[0][0]=0; beam_Memory_STAT[0][1]=0; beam_Memory_STAT[0][2]=0; beam_Memory_STAT[0][3]=0; beam_Memory_STAT[0][4]=0;
|
|
|
|
|
for(i=1;i<=beam_nr_gc_boxed+beam_nr_gc_heap;i++) {
|
|
|
|
|
beam_Memory_STAT[0][0]+=beam_Memory_STAT[i][0];
|
|
|
|
|
beam_Memory_STAT[0][1]+=beam_Memory_STAT[i][1];
|
|
|
|
|
beam_Memory_STAT[0][2]+=beam_Memory_STAT[i][2];
|
|
|
|
|
beam_Memory_STAT[0][3]+=beam_Memory_STAT[i][3];
|
|
|
|
|
beam_Memory_STAT[0][4]+=beam_Memory_STAT[i][4];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
printf("GC %4d Time=%ld H=%ld to %ld (%3.2f) Box=%ld to %ld (%3.2f)\n",
|
2006-03-24 16:19:31 +00:00
|
|
|
|
i, beam_Memory_STAT[i][0], beam_Memory_STAT[i][1], beam_Memory_STAT[i][3],
|
|
|
|
|
((float) beam_Memory_STAT[i][3]/beam_Memory_STAT[i][1])*100 , beam_Memory_STAT[i][2], beam_Memory_STAT[i][4],
|
|
|
|
|
((float) beam_Memory_STAT[i][4]/beam_Memory_STAT[i][2])*100);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
i--;
|
|
|
|
|
printf("\nRESUME GC: Time=%ld H=%ld to %ld (%3.2f) Box=%ld to %ld (%3.2f)\n",
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_Memory_STAT[0][0]/i, beam_Memory_STAT[0][1]/i, beam_Memory_STAT[0][3]/i,
|
|
|
|
|
100.0-((float) beam_Memory_STAT[0][3]/beam_Memory_STAT[0][1])*100 , beam_Memory_STAT[0][2]/i, beam_Memory_STAT[0][4]/i,
|
|
|
|
|
100.0-((float) beam_Memory_STAT[0][4]/beam_Memory_STAT[0][2])*100);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
} else {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
printf("Heap Mem Requested %ld (%.2fKb) (%.2fMB) \n", ((unsigned long) beam_H-beam_START_ADDR_HEAP), ((unsigned long) beam_H-beam_START_ADDR_HEAP)/1024.0, ((unsigned long) beam_H-beam_START_ADDR_HEAP)/1048576.0);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
printf("-------------------------------------------------------------------\n");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************\
|
|
|
|
|
* Memory Management routines *
|
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
|
|
void initialize_memory_areas()
|
|
|
|
|
{
|
|
|
|
|
static int first_time=1;
|
|
|
|
|
|
|
|
|
|
if (first_time) {
|
|
|
|
|
first_time=0;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_IndexFree=(Cell **) malloc(INDEX_SIZE*POINTER_SIZE);
|
|
|
|
|
if ((void *) beam_IndexFree==(void *)NULL) abort_eam("Memory Initialization Error IndexFree\n");
|
|
|
|
|
|
|
|
|
|
beam_START_ADDR_HEAP=(unsigned long) malloc(MEM_H+MEM_BOXES+MEM_VARS);
|
|
|
|
|
if ((void *)beam_START_ADDR_HEAP==(void *)NULL) abort_eam("Memory Initialization Error Heap+Boxes\n");
|
|
|
|
|
beam_START_ADDR_BOXES=beam_START_ADDR_HEAP+MEM_H;
|
|
|
|
|
beam_END_H=beam_START_ADDR_HEAP+MEM_H;
|
|
|
|
|
beam_END_BOX=beam_START_ADDR_BOXES+MEM_BOXES;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_sp=(Cell *) beam_END_H; beam_sp-=2;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextVar=(struct PERM_VAR *) beam_END_BOX;
|
|
|
|
|
beam_H=(Cell *) beam_START_ADDR_HEAP;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#if GARBAGE_COLLECTOR!=2
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextFree=(Cell *) beam_END_BOX;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#else
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextFree=(Cell *) beam_START_ADDR_BOXES;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_MemGoing=1;
|
|
|
|
|
memset(beam_IndexFree,0,INDEX_SIZE*POINTER_SIZE);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
{ int i,max;
|
|
|
|
|
max=MEM_VARS/PERM_VAR_SIZE;
|
|
|
|
|
for(i=0;i<max-1;i++) {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextVar[i].next=&beam_NextVar[i+1];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextVar[max-1].next=NULL;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_varlocals=NULL;
|
|
|
|
|
beam_USE_SAME_ANDBOX=NULL;
|
|
|
|
|
beam_nr_alternative=NULL;
|
|
|
|
|
beam_nr_call=NULL;
|
|
|
|
|
beam_nr_gc_heap=0;
|
|
|
|
|
beam_nr_gc_boxed=0;
|
|
|
|
|
beam_Mode=READ;
|
|
|
|
|
beam_VAR_TRAIL_NR=0;
|
|
|
|
|
beam_nr_call_forking=0;
|
|
|
|
|
beam_Mem_FULL=0;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#if Memory_Stat
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_TOTAL_MEM=0; beam_MEM_REUSED=0; beam_TOTAL_TEMPS=0; beam_TEMPS_REUSED=0; beam_TOTAL_PERMS=0; beam_PERMS_REUSED=0;
|
|
|
|
|
memset(beam_Memory_STAT,0,MAX_MEMORYSTAT*5*sizeof(unsigned long));
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INLINE int HEAP_MEM_FULL(void)
|
|
|
|
|
{
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_MemGoing==1) {
|
|
|
|
|
if ((unsigned long)beam_H>(unsigned long)(beam_START_ADDR_HEAP+MEM_H/2)) {
|
|
|
|
|
beam_Mem_FULL|=2;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if ((unsigned long) beam_H>(unsigned long)(beam_START_ADDR_HEAP+MEM_H)) {
|
|
|
|
|
beam_Mem_FULL|=2;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
return(beam_Mem_FULL);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE Cell *request_memory(int size) /* size in bytes */
|
|
|
|
|
{
|
|
|
|
|
register Cell *mem;
|
|
|
|
|
register int size_cells;
|
|
|
|
|
|
|
|
|
|
if (size==0) return NULL;
|
|
|
|
|
size_cells=size/CELL_SIZE;
|
|
|
|
|
|
|
|
|
|
#if !Fast_go
|
|
|
|
|
if (size_cells> INDEX_SIZE)
|
|
|
|
|
abort_eam("Foi pedido um block de memoria grande demais !!! \n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if Debug & Debug_MEMORY
|
|
|
|
|
printf("Requesting memory size %d\n",size_cells);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if HYBRID_BOXMEM
|
2006-03-24 16:19:31 +00:00
|
|
|
|
mem=beam_IndexFree[(unsigned) size_cells];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#if Memory_Stat
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_TOTAL_MEM+=size;
|
|
|
|
|
if (mem!=NULL) beam_MEM_REUSED+=size;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
if (mem==NULL) {
|
|
|
|
|
|
|
|
|
|
#else /* GC Only */
|
|
|
|
|
#if Memory_Stat
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_TOTAL_MEM+=size;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
if (1) {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if GARBAGE_COLLECTOR!=2
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextFree-=size_cells;
|
|
|
|
|
mem=beam_NextFree;
|
|
|
|
|
if (beam_NextFree< (Cell *) beam_START_ADDR_BOXES) abort_eam("No more BOX_MEM \n");
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#else
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_MemGoing==1) {
|
|
|
|
|
mem=beam_NextFree;
|
|
|
|
|
beam_NextFree+=size_cells;
|
|
|
|
|
if (beam_NextFree> (Cell *) ( beam_START_ADDR_BOXES+MEM_BOXES/2)) beam_Mem_FULL |= 1;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
} else {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_NextFree-=size_cells;
|
|
|
|
|
mem=beam_NextFree;
|
|
|
|
|
if (beam_NextFree< (Cell *) ( beam_START_ADDR_BOXES+MEM_BOXES/2)) beam_Mem_FULL |=1;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_IndexFree[(unsigned) size_cells]=(Cell *) *mem;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if Clear_MEMORY & 1
|
|
|
|
|
memset(mem,0,size); /* NOT REALLY NECESSARY, use only to detect possible errors*/
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return(mem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if HYBRID_BOXMEM==0
|
|
|
|
|
void free_memory(Cell *mem,int size) {
|
|
|
|
|
#if Clear_MEMORY & 2
|
|
|
|
|
memset(mem,0,size);
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
#else
|
|
|
|
|
INLINE void free_memory(Cell *mem,int size) /* size in bytes */
|
|
|
|
|
{
|
2005-10-09 22:13:57 +01:00
|
|
|
|
register int size_cells;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
if (size==0 || mem==NULL) return;
|
|
|
|
|
|
|
|
|
|
size_cells=size/CELL_SIZE;
|
|
|
|
|
|
|
|
|
|
#if Clear_MEMORY & 2
|
|
|
|
|
memset(mem,0,size); /* NOT REALLY NECESSARY, use only to detect possible errors*/
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if Debug & Debug_MEMORY
|
|
|
|
|
printf("Freeing memory size %d\n",size_cells);
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
*mem=(Cell) beam_IndexFree[size_cells];
|
|
|
|
|
beam_IndexFree[size_cells]=mem;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
INLINE void get_arguments(int nr, Cell *a)
|
|
|
|
|
{
|
|
|
|
|
register int i;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
for(i=1;i<=nr;i++) beam_X[i]=a[i];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INLINE Cell *save_arguments(int nr) /* nr arguments */
|
|
|
|
|
{
|
|
|
|
|
if (!nr) return(NULL);
|
|
|
|
|
{
|
|
|
|
|
register int i;
|
|
|
|
|
register Cell *a;
|
|
|
|
|
|
|
|
|
|
a=(Cell *)request_memory((nr+1)*CELL_SIZE);
|
|
|
|
|
a[0]=nr+1;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
for(i=1;i<=nr;i++) a[i]=beam_X[i];
|
2005-09-08 23:36:16 +01:00
|
|
|
|
return(a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INLINE void remove_memory_arguments(Cell *a)
|
|
|
|
|
{
|
|
|
|
|
if (a==NULL) return;
|
2006-04-08 15:56:48 +01:00
|
|
|
|
#if !Fast_go
|
|
|
|
|
if (a[0]<1 || a[0]>1000)
|
|
|
|
|
printf("%d Numero Invalido de Argumentos............\n",a[0]);
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-09-08 23:36:16 +01:00
|
|
|
|
free_memory(a,a[0]*CELL_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct PERM_VAR *request_permVar(struct AND_BOX *a) {
|
|
|
|
|
struct PERM_VAR *pv;
|
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
|
|
|
|
static struct PERM_VAR *old=NULL;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_TOTAL_PERMS+=PERM_VAR_SIZE;
|
|
|
|
|
if (old<=beam_NextVar) old=beam_NextVar;
|
|
|
|
|
else beam_PERMS_REUSED+=PERM_VAR_SIZE;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
#if Debug && Debug_MEMORY
|
2005-09-08 23:36:16 +01:00
|
|
|
|
printf("Requesting a permVar...\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !Fast_go
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_NextVar->next==NULL) { printf("Fim da memoria para variaveis\n"); exit (-1); }
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
pv=beam_NextVar;
|
|
|
|
|
beam_NextVar=beam_NextVar->next;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
pv->value=(Cell) &(pv->value);
|
|
|
|
|
pv->home=a;
|
|
|
|
|
pv->suspensions=NULL;
|
|
|
|
|
pv->yapvar=NULL;
|
|
|
|
|
pv->next=a->perms;
|
|
|
|
|
a->perms=pv;
|
|
|
|
|
return (pv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void free_permVar(struct PERM_VAR *v) {
|
|
|
|
|
#if Clear_MEMORY
|
|
|
|
|
v->value=(Cell) NULL;
|
|
|
|
|
v->home=(struct AND_BOX *) NULL;
|
|
|
|
|
v->suspensions=(struct SUSPENSIONS_VAR *) NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if Debug & Debug_MEMORY
|
|
|
|
|
printf("Freeing a permVar...\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
v->next=beam_NextVar;
|
|
|
|
|
beam_NextVar=v;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-10-09 22:13:57 +01:00
|
|
|
|
INLINE Cell *request_memory_locals(int nr)
|
2005-09-08 23:36:16 +01:00
|
|
|
|
{
|
|
|
|
|
Cell *l;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
|
|
|
|
Cell *old;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
old=beam_NextFree;
|
|
|
|
|
beam_TOTAL_TEMPS+=CELL_SIZE*(nr+1);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if Debug_MEMORY
|
|
|
|
|
printf("Requesting Memory for %d+1 locals...\n",nr);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
l=(Cell *)request_memory(CELL_SIZE*(nr+1));
|
|
|
|
|
l[0]=nr;
|
|
|
|
|
l++;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<nr;i++) {
|
|
|
|
|
l[i]=(Cell) &l[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (old==beam_NextFree) beam_TEMPS_REUSED+=CELL_SIZE*(nr+1);
|
2005-09-08 23:36:16 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return(l);
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-09 22:13:57 +01:00
|
|
|
|
INLINE Cell *request_memory_locals_noinit(int nr)
|
|
|
|
|
{
|
|
|
|
|
Cell *l;
|
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
|
|
|
|
Cell *old;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
old=beam_NextFree;
|
|
|
|
|
beam_TOTAL_TEMPS+=CELL_SIZE*(nr+1);
|
2005-10-09 22:13:57 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if Debug_MEMORY
|
|
|
|
|
printf("Requesting Memory for %d+1 locals (not initialized)...\n",nr);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
l=(Cell *)request_memory(CELL_SIZE*(nr+1));
|
|
|
|
|
l[0]=nr;
|
|
|
|
|
l++;
|
|
|
|
|
|
|
|
|
|
#if Memory_Stat
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (old==beam_NextFree) beam_TEMPS_REUSED+=CELL_SIZE*(nr+1);
|
2005-10-09 22:13:57 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return(l);
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-08 23:36:16 +01:00
|
|
|
|
INLINE void free_memory_locals(Cell *l)
|
|
|
|
|
{
|
|
|
|
|
if (l==NULL || l[-1]==0) return;
|
|
|
|
|
|
|
|
|
|
#if Debug_MEMORY
|
|
|
|
|
printf("Freeing Memory for %ld+1 locals...\n",l[-1]);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
free_memory((Cell *) &l[-1], CELL_SIZE*(l[-1]+1));
|
|
|
|
|
l[-1]=0; /* <20> necess<73>rio para evitar apagar este vector novamente
|
|
|
|
|
porque varias calls podem estar a referenciar o mesmo vector locals */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************\
|
|
|
|
|
* Manipulating And-Or-Boxes structures *
|
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void del_andbox_and_sons(struct AND_BOX *andbox )
|
|
|
|
|
{
|
|
|
|
|
register struct status_and *ncall;
|
|
|
|
|
|
|
|
|
|
if (andbox==NULL) return;
|
|
|
|
|
|
|
|
|
|
remove_all_externals(andbox);
|
|
|
|
|
delfrom_suspensions_list(andbox->suspended);
|
|
|
|
|
|
|
|
|
|
ncall=andbox->calls;
|
|
|
|
|
while(ncall!=NULL) {
|
|
|
|
|
del_orbox_and_sons(ncall->call);
|
|
|
|
|
{
|
|
|
|
|
struct status_and *ncall_old;
|
|
|
|
|
ncall_old=ncall;
|
|
|
|
|
ncall=ncall->next;
|
|
|
|
|
free_memory_locals(ncall_old->locals);
|
|
|
|
|
free_memory((Cell *) ncall_old,STATUS_AND_SIZE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
remove_list_perms(andbox);
|
|
|
|
|
free_memory((Cell *) andbox,ANDBOX_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void del_orbox_and_sons(struct OR_BOX *orbox)
|
|
|
|
|
{
|
|
|
|
|
struct status_or *so;
|
|
|
|
|
Cell *a=NULL;
|
|
|
|
|
|
|
|
|
|
if (orbox==NULL) return;
|
|
|
|
|
|
|
|
|
|
so=orbox->alternatives;
|
|
|
|
|
while (so!=NULL) {
|
|
|
|
|
struct status_or *old;
|
|
|
|
|
del_andbox_and_sons(so->alternative);
|
|
|
|
|
a=so->args;
|
|
|
|
|
old=so;
|
|
|
|
|
so=so->next;
|
|
|
|
|
free_memory((Cell *) old,STATUS_OR_SIZE);
|
|
|
|
|
}
|
|
|
|
|
remove_memory_arguments(a); /* remove args */
|
|
|
|
|
free_memory((Cell *) orbox,ORBOX_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE struct status_and *remove_call_from_andbox(struct status_and *ncall, struct AND_BOX *a)
|
|
|
|
|
{
|
|
|
|
|
register int nr;
|
|
|
|
|
struct status_and *r;
|
|
|
|
|
nr=a->nr_all_calls;
|
|
|
|
|
nr--;
|
|
|
|
|
a->nr_all_calls=nr;
|
|
|
|
|
if (nr==0) {
|
|
|
|
|
a->calls=NULL;
|
|
|
|
|
} else {
|
|
|
|
|
if (ncall->previous!=NULL) {
|
|
|
|
|
ncall->previous->next=ncall->next;
|
|
|
|
|
} else a->calls=ncall->next;
|
|
|
|
|
|
|
|
|
|
if (ncall->next!=NULL) {
|
|
|
|
|
ncall->next->previous=ncall->previous;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r=ncall->next;
|
|
|
|
|
{ /* vou ver se as locals ainda estao a ser usadas por outra ncall */
|
|
|
|
|
int aSerUsada=0;
|
|
|
|
|
struct status_and *l;
|
|
|
|
|
l=ncall->previous;
|
|
|
|
|
while (l!=NULL) {
|
|
|
|
|
if (l->locals==ncall->locals) { aSerUsada=1; break; }
|
|
|
|
|
l=l->previous;
|
|
|
|
|
}
|
|
|
|
|
l=r;
|
|
|
|
|
while (aSerUsada==0 && l!=NULL) {
|
|
|
|
|
if (l->locals==ncall->locals) { aSerUsada=1; break; }
|
|
|
|
|
l=l->next;
|
|
|
|
|
}
|
|
|
|
|
// aSerUsada=1; /* CUIDADO ao apagar as var locals da call */
|
|
|
|
|
if (aSerUsada==0) free_memory_locals(ncall->locals);
|
|
|
|
|
}
|
|
|
|
|
free_memory((Cell *) ncall,STATUS_AND_SIZE);
|
|
|
|
|
return(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE void totop_suspensions_list(struct SUSPENSIONS *b)
|
|
|
|
|
{
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_su==b) return; /* is already on top of list */
|
|
|
|
|
if (beam_su->prev==b) { beam_su=b; return; } /* It was the last one */
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
|
|
|
|
b->prev->next=b->next;
|
|
|
|
|
b->next->prev=b->prev;
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
b->next=beam_su;
|
|
|
|
|
b->prev=beam_su->prev;
|
|
|
|
|
beam_su->prev=b;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
b->prev->next=b;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_su=b;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void waking_boxes_suspended_on_var(struct PERM_VAR *v)
|
|
|
|
|
{
|
|
|
|
|
struct SUSPENSIONS_VAR *s;
|
|
|
|
|
|
|
|
|
|
s=v->suspensions;
|
|
|
|
|
|
|
|
|
|
while(s!=NULL) {
|
|
|
|
|
register struct AND_BOX *a;
|
|
|
|
|
#if Debug
|
|
|
|
|
printf("Waking and_box assigment changed on a var that forced and_box to suspend \n");
|
|
|
|
|
#endif
|
|
|
|
|
a=s->and_box;
|
|
|
|
|
totop_suspensions_list(a->suspended);
|
|
|
|
|
a->nr_alternative->state|=WAKE;
|
|
|
|
|
s=s->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* THE FALLOWING ROTINES ARE TO BE APPLYED TO THE SUSPENSION LIST
|
|
|
|
|
(DO NOT USE IT TO THE SUSPENSIONS ON THE LOCAL_VAR) */
|
|
|
|
|
INLINE struct SUSPENSIONS *addto_suspensions_list(struct AND_BOX *a,int r)
|
|
|
|
|
{
|
|
|
|
|
struct SUSPENSIONS *s;
|
|
|
|
|
|
|
|
|
|
if (a->suspended) return(a->suspended); /* already suspended */
|
|
|
|
|
|
|
|
|
|
s=(struct SUSPENSIONS *) request_memory(SUSPENSIONS_SIZE);
|
|
|
|
|
s->and_box=a;
|
|
|
|
|
s->reason=r;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (beam_su==NULL) {
|
2005-09-08 23:36:16 +01:00
|
|
|
|
s->next=s;
|
|
|
|
|
s->prev=s;
|
2006-03-24 16:19:31 +00:00
|
|
|
|
beam_su=s;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
} else {
|
2006-03-24 16:19:31 +00:00
|
|
|
|
s->next=beam_su;
|
|
|
|
|
s->prev=beam_su->prev;
|
|
|
|
|
beam_su->prev=s;
|
|
|
|
|
if (beam_su->next==beam_su) { /* so existem 2 elementos na lista */
|
|
|
|
|
beam_su->next=s;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
} else {
|
|
|
|
|
s->prev->next=s;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void delfrom_suspensions_list(struct SUSPENSIONS *b)
|
|
|
|
|
{
|
|
|
|
|
if (b==NULL) return;
|
|
|
|
|
#if !Fast_go
|
|
|
|
|
if ( b->and_box->suspended==NULL)
|
|
|
|
|
abort_eam("Nunca deveria acontecer no delfrom_suspensions_list ?????\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
remove_all_externals_suspensions(b->and_box);
|
|
|
|
|
b->and_box->suspended=NULL;
|
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (b==beam_su) beam_su=b->next;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
|
2006-03-24 16:19:31 +00:00
|
|
|
|
if (b==beam_su) { /* so existe um */
|
|
|
|
|
beam_su=NULL;
|
2005-09-08 23:36:16 +01:00
|
|
|
|
} else {
|
|
|
|
|
b->prev->next=b->next;
|
|
|
|
|
b->next->prev=b->prev;
|
|
|
|
|
}
|
|
|
|
|
free_memory((Cell *) b,SUSPENSIONS_SIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE void change_perm_var_suspensions(struct PERM_VAR *v,struct AND_BOX *andbox,struct AND_BOX *new)
|
|
|
|
|
{
|
|
|
|
|
struct SUSPENSIONS_VAR *s;
|
|
|
|
|
|
|
|
|
|
s=v->suspensions;
|
|
|
|
|
while(s!=NULL)
|
|
|
|
|
{
|
|
|
|
|
if (s->and_box==andbox) {
|
|
|
|
|
s->and_box=new;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
s=s->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* MANIPULATE PERM VARS SUSPENSIONS */
|
|
|
|
|
|
|
|
|
|
INLINE void remove_from_perm_var_suspensions(struct PERM_VAR *v,struct AND_BOX *andbox)
|
|
|
|
|
{
|
|
|
|
|
struct SUSPENSIONS_VAR *s,*prev=NULL;
|
|
|
|
|
|
|
|
|
|
if (v==NULL) {
|
|
|
|
|
#if !Fast_go
|
|
|
|
|
abort_eam("Nunca deveria acontecer no remove_from_perm_var_suspensions ?????\n");
|
|
|
|
|
#endif
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s=v->suspensions;
|
|
|
|
|
while(s!=NULL)
|
|
|
|
|
{
|
|
|
|
|
struct SUSPENSIONS_VAR *next;
|
|
|
|
|
next=s->next;
|
|
|
|
|
if (s->and_box==andbox) {
|
|
|
|
|
if (prev==NULL) {
|
|
|
|
|
v->suspensions=s->next;
|
|
|
|
|
} else prev->next=s->next;
|
|
|
|
|
free_memory((Cell *) s,SUSPENSIONS_VAR_SIZE);
|
|
|
|
|
} else { /* acordar as boxes restantes porque houve uma alteracao */
|
|
|
|
|
s->and_box->nr_alternative->state |=WAKE;
|
|
|
|
|
prev=s;
|
|
|
|
|
}
|
|
|
|
|
s=next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void remove_all_externals_suspensions(struct AND_BOX *andbox)
|
|
|
|
|
{
|
|
|
|
|
struct EXTERNAL_VAR *e;
|
|
|
|
|
|
|
|
|
|
e=andbox->externals;
|
|
|
|
|
while(e) {
|
|
|
|
|
remove_from_perm_var_suspensions(e->var,andbox);
|
|
|
|
|
e=e->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void remove_all_externals(struct AND_BOX *andbox)
|
|
|
|
|
{
|
|
|
|
|
struct EXTERNAL_VAR *e;
|
|
|
|
|
|
|
|
|
|
e=andbox->externals;
|
|
|
|
|
while(e) {
|
|
|
|
|
struct EXTERNAL_VAR *next;
|
|
|
|
|
next=e->next;
|
|
|
|
|
remove_from_perm_var_suspensions(e->var,andbox);
|
|
|
|
|
free_memory((Cell *)e,EXTERNAL_VAR_SIZE);
|
|
|
|
|
e=next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void remove_list_perms(struct AND_BOX *a)
|
|
|
|
|
{
|
|
|
|
|
struct PERM_VAR *l,*oldl;
|
|
|
|
|
|
|
|
|
|
l=a->perms;
|
|
|
|
|
a->perms=NULL;
|
|
|
|
|
while(l) {
|
|
|
|
|
oldl=l;
|
|
|
|
|
l=oldl->next;
|
|
|
|
|
free_permVar(oldl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE void move_perm_vars(struct AND_BOX *b, struct AND_BOX *a) /* (from b to a) */
|
|
|
|
|
{
|
|
|
|
|
struct PERM_VAR *l,*old;
|
|
|
|
|
|
|
|
|
|
l=b->perms;
|
|
|
|
|
if (l==NULL) return;
|
|
|
|
|
do {
|
|
|
|
|
old=l;
|
|
|
|
|
l->home=a;
|
|
|
|
|
if (l->suspensions) change_perm_var_suspensions(l,b,a);
|
|
|
|
|
l=l->next;
|
|
|
|
|
} while(l!=NULL);
|
|
|
|
|
old->next=a->perms;
|
|
|
|
|
a->perms=b->perms;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void add_to_list_perms(struct PERM_VAR *var,struct AND_BOX *a)
|
|
|
|
|
{
|
|
|
|
|
var->next=a->perms;
|
|
|
|
|
a->perms=var;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* change all suspended external references of perm var o to perm var d */
|
|
|
|
|
void change_from_to(struct PERM_VAR *o,struct PERM_VAR *d) {
|
|
|
|
|
struct SUSPENSIONS_VAR *s,*last;
|
|
|
|
|
|
|
|
|
|
#if Debug
|
|
|
|
|
printf("Change Vars from one andbox to another\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|