Example #1
0
void free_unused_strings() {
  size_t i;
  void *ptr, *prevptr;
  int used = 0, unused = 0;

  for (i = 0; i < string_table.size; i++) {
    if (string_table.table[i] != NULL) {
      prevptr = &string_table.table[i];
      ptr = *(void **)prevptr;
      while (ptr != NULL) {
	if ((*(Integer *)ptr) & 1) {
	  used++;
	  (*(Integer *)ptr) &= ~1;
	  prevptr = ptr;
	  ptr = *(void **)ptr;
	} else {
	  unused++;
	  // printf("fs: %s\n",(((char *)ptr))+sizeof(void *));
	  *(void **)prevptr = *(void **)ptr;
	  mem_dealloc(ptr,strlen(((char *)ptr)+sizeof(void *))+sizeof(void *)+1,STRING_SPACE);
	  //	  *(((char *)ptr)+sizeof(void *)) = '?';
	  ptr = *(void **)prevptr;
	  string_table.contains--;
	  //	  ptr = *(void **)ptr;  // replace with above when have marked all
	}
      }
    }
  }
  //  if (unused > 0) printf("%d",unused);
  //  printf("string_table scanned. used=%d, unused=%d\n",used,unused);
}
Example #2
0
void expand_symbol_table() {

  Pair *new_table, *bucket_ptr, cur_pair, next_pair;
  Psc cur_psc;
  size_t index, new_size, new_index;

  new_size = next_prime(symbol_table.size);
  new_table = (Pair *)mem_calloc(new_size, sizeof(void *),ATOM_SPACE);

  for (bucket_ptr = (Pair *)symbol_table.table, index = 0;
       index < symbol_table.size;  bucket_ptr++, index++)

    for (cur_pair = *bucket_ptr; cur_pair != NULL; cur_pair = next_pair) {
      next_pair = pair_next(cur_pair);
      cur_psc = pair_psc(cur_pair);
      new_index = hash(get_name(cur_psc), get_arity(cur_psc), new_size);
      pair_next(cur_pair) = new_table[new_index];
      new_table[new_index] = cur_pair;
    }

  mem_dealloc((void *)symbol_table.table,symbol_table.size,ATOM_SPACE);
  symbol_table.size = new_size;
  symbol_table.table = (void **)new_table;
  /*printf("expanded atom table to: %d\n",new_size);*/
}
Example #3
0
void *worker_thread(void *pmyid) {
  long myid, validateLength, length, i, j, k, l, m;
  float sum;
  
  float *src1, *src2, *dst;
  float *asrc1, *asrc2, *adst;
    
  myid = (long) pmyid;
  printf("THREAD#%02ld START!!!\n", myid);

//cpu affinity  
  pinCPU(pmyid);
  
//init and alloc  
  mem_alloc_init(pmyid);
  
//sync-point
//  worker_thread_sync(pmyid);

//do-work 
  matmul_c(pmyid); 
   
//validate
  matmul_validate(pmyid);
    
//clean-up
  mem_dealloc(pmyid);
  
  if(DODEBUG) fflush(stdout);
  printf("THREAD#%02ld END!!!\n", myid);
  if(DODEBUG) fflush(stdout);
    
  if(myid) pthread_exit((void*)pmyid);
}
Example #4
0
static int socket_send(CTXTdeclc int *rc, int timeout) {
  SOCKET sock_handle = (SOCKET) ptoc_int(CTXTc 2);
  char *send_msg_aux = ptoc_string(CTXTc 3);
  size_t msg_body_len, full_msg_len, network_encoded_len;
  char *message_buffer;

  if (!write_select(sock_handle, timeout)) {
    return TIMED_OUT;
  }

  /* We we add 1 since the message is a string that ends with a '\0' (this is
     how it is pased from XSB to send_msg_aux) */
  msg_body_len = strlen(send_msg_aux)+1;
  full_msg_len = msg_body_len+XSB_MSG_HEADER_LENGTH;

  /* We use the first XSB_MSG_HEADER_LENGTH bytes for the message size. */
  message_buffer = mem_calloc(full_msg_len, sizeof(char),LEAK_SPACE);

  network_encoded_len =  htonl((u_long)msg_body_len); 
  memcpy((void*)(message_buffer), (void *)&network_encoded_len, XSB_MSG_HEADER_LENGTH);
  strcpy(message_buffer+XSB_MSG_HEADER_LENGTH, send_msg_aux);

  *rc = sendto(sock_handle, message_buffer, (int)full_msg_len, 0, NULL, 0);
  mem_dealloc(message_buffer,full_msg_len*sizeof(char),LEAK_SPACE);

  return NORMAL_TERMINATION;
}
Example #5
0
void set_xsbinfo_dir () {
  struct stat *fileinfo = mem_alloc(1*sizeof(struct stat),LEAK_SPACE);
  char old_xinitrc[MAXPATHLEN], new_xinitrc[MAXPATHLEN],
    user_config_dir[MAXPATHLEN], user_arch_dir[MAXPATHLEN];
  int retcode;

  if (!fileinfo) {
    xsb_abort("No core memory to allocate stat structure.\n");
  }
  snprintf(xsbinfo_dir_gl, MAXPATHLEN, "%s%c.xsb", user_home_gl, SLASH);
  snprintf(old_xinitrc, MAXPATHLEN, "%s%c.xsbrc", user_home_gl, SLASH);
  snprintf(new_xinitrc, MAXPATHLEN, "%s%cxsbrc", xsbinfo_dir_gl, SLASH);
  snprintf(user_config_dir, MAXPATHLEN, "%s%cconfig", xsbinfo_dir_gl, SLASH);
  snprintf(user_arch_dir, MAXPATHLEN, "%s%c%s", user_config_dir, SLASH, FULL_CONFIG_NAME);

  /* Create USER_HOME/.xsb directory, if it doesn't exist. */
  check_create_dir(xsbinfo_dir_gl);
  check_create_dir(user_config_dir);
  check_create_dir(user_arch_dir);
  retcode = stat(old_xinitrc, fileinfo);

  if ((retcode == 0) && (stat(new_xinitrc, fileinfo) != 0)) {
    xsb_warn("It appears that you have an old-style `.xsbrc' file!\n           The XSB initialization file is now %s.\n           If your `.xinitrc' defines the `library_directory' predicate,\n           please consult the XSB manual for the new conventions.", new_xinitrc);
  }
  mem_dealloc(fileinfo,1*sizeof(struct stat),LEAK_SPACE);
}
Example #6
0
/* Check if PATH exists. Create if it doesn't. Bark if it can't create or if
   PATH exists, but isn't a directory. */
static void check_create_dir(char *path) {
  struct stat *fileinfo = mem_alloc(1*sizeof(struct stat),LEAK_SPACE);
  int retcode = stat(path, fileinfo);

  if (!fileinfo) {
    xsb_abort("No core memory to allocate stat structure.\n");
  }

  if (retcode == 0 && ! S_ISDIR(fileinfo->st_mode)) {
    xsb_warn("File `%s' is not a directory!\n           XSB uses this directory to store data.", path);
    /* exit(1); */
  }

  if (retcode != 0) 
#ifdef WIN_NT
    retcode = mkdir(path);
#else
    retcode = mkdir(path, 0755);
#endif

  if (retcode != 0) {
    xsb_warn("Cannot create directory `%s'!\n           XSB uses this directory to store data.", path);
    /* exit(1); */
  }
  mem_dealloc(fileinfo,1*sizeof(struct stat),LEAK_SPACE);
}
Example #7
0
void expand_string_table() {

  void **new_table, **bucket_ptr, **cur_entry, **next_entry;
  char *string;
  size_t index, new_size, new_index;

  new_size = next_prime(string_table.size);
  new_table = (void **)mem_calloc(new_size, sizeof(void *),STRING_SPACE);

  for (bucket_ptr = string_table.table, index = 0;
       index < string_table.size;
       bucket_ptr++, index++)
    for (cur_entry = (void **)*bucket_ptr;
	 cur_entry != NULL;
	 cur_entry = next_entry) {
      next_entry = (void **)*cur_entry;
      string = (char *)(cur_entry + 1);
      new_index = hash(string, 0, new_size);
      *cur_entry = new_table[new_index];
      new_table[new_index] = (void *)cur_entry;
    }

  mem_dealloc((void *)string_table.table,string_table.size*sizeof(void *),STRING_SPACE);
  string_table.size = new_size;
  string_table.table = new_table;
  //  printf("expanded string table to: %ld\n",new_size);
}
Example #8
0
/* utility function to destroy a select call */
static void select_destroy(CTXTdeclc char *connection_name)
{
  int i;
  int connectname_found = FALSE;

  SYS_MUTEX_LOCK(MUTEX_SOCKETS);
  for (i=0; i < MAXCONNECT; i++) {
    if(connections[i].empty_flag==FALSE) {
      /* find the matching connection_name to destroy */
      if (strcmp(connection_name, connections[i].connection_name) == 0) {
	connectname_found = TRUE;
	      
	/* destroy the corresponding structure */
	FD_ZERO(&connections[i].readset);
	FD_ZERO(&connections[i].writeset);
	FD_ZERO(&connections[i].exceptionset);

	connections[i].connection_name = NULL;
	connections[i].maximum_fd = 0;

	/* free the fds obtained by mem_alloc() */
	mem_dealloc(connections[i].read_fds,connections[i].sizer,OTHER_SPACE);
	mem_dealloc(connections[i].write_fds,connections[i].sizew,OTHER_SPACE);
	mem_dealloc(connections[i].exception_fds,connections[i].sizee,OTHER_SPACE); 
      
	connections[i].sizer = 0;
	connections[i].sizew = 0 ;
	connections[i].sizee = 0 ;

	connections[i].empty_flag = TRUE; /* set the destroyed slot to empty */
	break;
      }
    }
  }
  SYS_MUTEX_UNLOCK(MUTEX_SOCKETS);
  
  /* if no matching connection_name */
  if (!connectname_found)
    xsb_abort("[SOCKET_SELECT_DESTROY] connection `%s' doesn't exist", 
	      connection_name);
  
  SQUASH_LINUX_COMPILER_WARN(connectname_found) ; 
}
Example #9
0
void leave(GtkWidget *widget, gpointer *data)
{
    draw_stop();
    save_config(widget);
    input_thread_stopper(data_handle);
    close_datasource(data_handle);
    /* Free all buffers */
    mem_dealloc();
    gtk_main_quit();
}
Example #10
0
void unload_seg(pseg s)
{
  pindex i1, i2 ;
  pseg prev, next ;

  /* free the index blocks */
  i1 = seg_index(s) ;
  while (i1) {
    i2 = i_next(i1) ;
    mem_dealloc((pb)i1, i_size(i1),COMPILED_SPACE);
    i1 = i2;
  }
  /* delete segment from segment dllist and dealloc it */
  next = seg_next(s) ;
  prev = seg_prev(s) ;
  if (next) seg_prev(next) = prev ;
  if (prev) seg_next(prev) = next ;
  if (last_text==s) last_text = prev ;
  mem_dealloc((pb)seg_hdr(s), seg_size(s),COMPILED_SPACE);
}
Example #11
0
void smFreeBlocks(Structure_Manager *pSM) {

  void *pCurBlock, *pNextBlock;

  pCurBlock = SM_CurBlock(*pSM);
  while ( IsNonNULL(pCurBlock) ) {
    pNextBlock = SMBlk_NextBlock(pCurBlock);
    mem_dealloc(pCurBlock,SM_NewBlockSize(*pSM),TABLE_SPACE);
    pCurBlock = pNextBlock;
  }
  SM_CurBlock(*pSM) = SM_NextStruct(*pSM) = SM_LastStruct(*pSM) = NULL;
  SM_AllocList(*pSM) = SM_FreeList(*pSM) = NULL;
}
Example #12
0
File: init.c Project: UIKit0/eXtace
void reinit_extace(int new_nsamp)
{

  /* Stop drawing the display */
    draw_stop();
    if(data_handle != -1) /* stop if previously opened */
      { 
	input_thread_stopper(data_handle);
	close_datasource(data_handle);
      }	

  /* Free all buffers */
        mem_dealloc();
	scope_begin_l = 0;
	scope_begin_l = 0;
	/* auto shift lag slightly to maintain good sync 
	 * The idea is the shift the lag slighly so that the "on-time" data
	 * is in the MIDDLE of the window function for better eye/ear matchup
	 */
	nsamp = new_nsamp;

	convolve_factor = floor(nsamp/width) < 3 ? floor(nsamp/width) : 3 ;
	if (convolve_factor == 0)
		convolve_factor = 1;
	recalc_markers = TRUE;
	recalc_scale = TRUE;	

	mem_alloc();
	setup_datawindow(NULL,(WindowFunction)window_func);
	ring_rate_changed();
	ring_pos=0;
	
	/* only start if it has been stopped above */
	if(data_handle != -1 && (data_handle=open_datasource(data_source)) >= 0)
	  {
#ifdef USING_FFTW2
		  fftw_destroy_plan(plan);
		  plan = fftw_create_plan(nsamp, FFTW_FORWARD, FFTW_ESTIMATE);
#elif USING_FFTW3
		  fftw_cleanup();
		  plan = fftw_plan_r2r_1d(nsamp, raw_fft_in, raw_fft_out,FFTW_R2HC, FFTW_ESTIMATE);
#endif
		  input_thread_starter(data_handle);
		  ring_rate_changed(); /* Fix all gui controls that depend on
					* ring_rate (adjustments and such
					*/
		  draw_start();
	  }
}
Example #13
0
xsbBool str_cat(CTXTdecl)
{
    char *str1, *str2, *tmpstr;
    size_t tmpstr_len;

    term = ptoc_tag(CTXTc 1);
    term2 = ptoc_tag(CTXTc 2);
    if (isatom(term) && isatom(term2)) {
        str1 = string_val(term);
        str2 = string_val(term2);
        tmpstr_len = strlen(str1) + strlen(str2) + 1;

        tmpstr = (char *)mem_alloc(tmpstr_len,LEAK_SPACE);
        strcpy(tmpstr, str1);
        strcat(tmpstr, str2);
        str1 = string_find(tmpstr, 1);
        mem_dealloc(tmpstr,tmpstr_len,LEAK_SPACE);
        return atom_unify(CTXTc makestring(str1), ptoc_tag(CTXTc 3));
    } else return FALSE;
}
Example #14
0
/* destruction is necessary for automatic VarString's,
   or else there will be a memory leak */
static inline void  vs_destroy(VarString *vstr)
{
  if (vstr->string == NULL) {
#ifdef DEBUG_VARSTRING
    fprintf(stderr,
	    "Attempt to deallocate uninitialized variable-length string\n");
    return;
#else
    return;
    //    xsb_bug("Attempt to deallocate uninitialized variable-length string");
#endif
  }
#ifdef DEBUG_VARSTRING
  fprintf(stderr,
	    "Deallocating a variable-length string\n");
#endif
  mem_dealloc(vstr->string,vstr->size,OTHER_SPACE);
  vstr->string    = NULL;
  vstr->size        = 0;
  vstr->length      = 0;
  vstr->increment   = 0;
}
void dfs_outedges(CTXTdeclc callnodeptr call1){
  callnodeptr cn;
  struct hashtable *h;	
  struct hashtable_itr *itr;
  int ctr = 0;

  int incr_callgraph_dfs_top = -1;
  int incr_callgraph_dfs_size; 
  IncrCallgraphDFSFrame   *incr_callgraph_dfs;

  //  printf("1) calling dfs %p; subgoal ",call1);  print_callnode(stddbg,call1); printf("\n");

  incr_callgraph_dfs =
    (IncrCallgraphDFSFrame *)  mem_alloc(10000*sizeof(IncrCallgraphDFSFrame), 
					 TABLE_SPACE);
  incr_callgraph_dfs_size = 10000;
  dfs_outedges_check_non_completed(CTXTc call1);
  if (!is_fact_in_callgraph(call1)) call1->deleted = 1;
  h=call1->outedges->hasht;
  if (hashtable1_count(h) > 0){
    //    printf("1-call1: %p \n",call1);
    push_dfs_frame(call1,0);
  }
  while (incr_callgraph_dfs_top > -1) {
    itr = 0;
    do {
      if (incr_callgraph_dfs[incr_callgraph_dfs_top].itr) {
	itr = incr_callgraph_dfs[incr_callgraph_dfs_top].itr;
	//	printf("1-top %d itr %p\n",incr_callgraph_dfs_top,itr);
	if (!hashtable1_iterator_advance(itr)) {  // last element in the hash
	  itr = 0;
	  cn = incr_callgraph_dfs[incr_callgraph_dfs_top].cn;
	  add_callnode(&affected_gl,cn);		
	  //	  printf("+ adding callnode %p\n",cn);
	  pop_dfs_frame;
	}
      }
      else {
	h=incr_callgraph_dfs[incr_callgraph_dfs_top].cn->outedges->hasht;
	if (hashtable1_count(h) > 0) {
	  itr = hashtable1_iterator(h);          // initialize
	  incr_callgraph_dfs[incr_callgraph_dfs_top].itr = itr;
	}
	else {
	  cn = incr_callgraph_dfs[incr_callgraph_dfs_top].cn;
	  add_callnode(&affected_gl,cn);		
	  //	  printf("+ adding callnode %p\n",cn);
	  pop_dfs_frame;
	}
      }
    } while (itr == 0 && incr_callgraph_dfs_top > -1);
    if (incr_callgraph_dfs_top > -1) {
      cn = hashtable1_iterator_value(itr);

      //      printf("top %d cn: %p itr: %p\n",incr_callgraph_dfs_top,cn,itr);
      //      printf("2) recursive dfs %p; subgoal ",cn);  print_callnode(stddbg,cn); printf("\n");

      cn->falsecount++;
      if (cn->deleted==0) {
	dfs_outedges_check_non_completed(CTXTc cn);
	cn->deleted = 1;
	//	h=cn->outedges->hasht;
	//	if (hashtable1_count(h) > 0) {
	  push_dfs_frame(cn,0);
	  //	}
      }
    }
  }
  mem_dealloc(incr_callgraph_dfs, incr_callgraph_dfs_size*sizeof(IncrCallgraphDFSFrame), 
	      TABLE_SPACE);
}
int  get_incr_sccs(CTXTdeclc Cell listterm) {
  Cell orig_listterm, intterm, node;
    long int node_num=0;
    int i = 0, dfn, component = 1;     int * dfn_stack; int dfn_top = 0, ret;
    SCCNode * nodes;
    struct hashtable_itr *itr;     struct hashtable* hasht; 
    XSB_Deref(listterm);
    hasht = create_hashtable1(HASH_TABLE_SIZE, hashid, equalkeys);
    orig_listterm = listterm;
    intterm = get_list_head(listterm);
    XSB_Deref(intterm);
    //    printf("listptr %p @%p\n",listptr,(CPtr) int_val(*listptr));
    insert_some(hasht,(void *) oint_val(intterm),(void *) node_num);
    node_num++; 

    listterm = get_list_tail(listterm);
    XSB_Deref(listterm);
    while (!isnil(listterm)) {
      intterm = get_list_head(listterm);
      XSB_Deref(intterm);
      node = oint_val(intterm);
      if (NULL == search_some(hasht, (void *)node)) {
	insert_some(hasht,(void *)node,(void *)node_num);
	node_num++;
      }
      listterm = get_list_tail(listterm);
      XSB_Deref(listterm);
    }
    nodes = (SCCNode *) mem_calloc(node_num, sizeof(SCCNode),OTHER_SPACE); 
    dfn_stack = (int *) mem_alloc(node_num*sizeof(int),OTHER_SPACE); 
    listterm = orig_listterm;; 
    //printf("listptr %p @%p\n",listptr,(void *)int_val(*(listptr)));
    intterm = get_list_head(listterm);
    XSB_Deref(intterm);
    nodes[0].node = (CPtr) oint_val(intterm);
    listterm = get_list_tail(listterm);
    XSB_Deref(listterm);
    i = 1;
    while (!isnil(listterm)) {
      intterm = get_list_head(listterm);
      XSB_Deref(intterm);
      node = oint_val(intterm);
      nodes[i].node = (CPtr) node;
      listterm = get_list_tail(listterm);
      XSB_Deref(listterm);
      i++;
    }
    itr = hashtable1_iterator(hasht);       
    SQUASH_LINUX_COMPILER_WARN(itr);
    //    do {
    //      printf("k %p val %p\n",hashtable1_iterator_key(itr),hashtable1_iterator_value(itr));
    //    } while (hashtable1_iterator_advance(itr));

    listterm = orig_listterm;
    //    printf("2: k %p v %p\n",(void *) int_val(*listptr),
    //	   search_some(hasht,(void *) int_val(*listptr)));

    //    while (!isnil(*listptr)) {  now all wrong...
    //      listptr = listptr + 1;
    //      node = int_val(*clref_val(listptr));
    //      printf("2: k %p v %p\n",(CPtr) node,search_some(hasht,(void *) node));
    //      listptr = listptr + 1;
    //    }
    dfn = 1;
    for (i = 0; i < node_num; i++) {
      if (nodes[i].dfn == 0) 
	xsb_compute_scc(nodes,dfn_stack,i,&dfn_top,hasht,&dfn,&component);
      //      printf("++component for node %d is %d (high %d)\n",i,nodes[i].component,component);
    }
    ret = return_scc_list(CTXTc  nodes, node_num);
    hashtable1_destroy(hasht,0);
    mem_dealloc(nodes,node_num*sizeof(SCCNode),OTHER_SPACE); 
    mem_dealloc(dfn_stack,node_num*sizeof(int),OTHER_SPACE); 
    return ret;
}
Example #17
0
/* in order to save builtin numbers, create a single socket function with
 * options socket_request(SockOperation,....)  */
xsbBool xsb_socket_request(CTXTdecl)
{
  int ecode = 0;  /* error code for socket ops */
  int timeout_flag;
  SOCKET sock_handle;
  int domain, portnum;
  SOCKADDR_IN socket_addr;
  struct linger sock_linger_opt;
  int rc;
  char *message_buffer = NULL; /* initialized to keep compiler happy */
  UInteger msg_len = 0;	  /* initialized to keep compiler happy */
  char char_read;

  switch (ptoc_int(CTXTc 1)) {
  case SOCKET_ROOT: /* this is the socket() request */
    /* socket_request(SOCKET_ROOT,+domain,-socket_fd,-Error,_,_,_) 
       Currently only AF_INET domain */
    domain = (int)ptoc_int(CTXTc 2); 
    if (!translate_domain(domain, &domain)) {
      return FALSE;
    }
    
    sock_handle = socket(domain, SOCK_STREAM, IPPROTO_TCP);
	
    /* error handling */
    if (BAD_SOCKET(sock_handle)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_REQUEST");
    } else {
      ecode = SOCK_OK;
    }

    ctop_int(CTXTc 3, (SOCKET) sock_handle);
	
    return set_error_code(CTXTc ecode, 4, "SOCKET_REQUEST");

  case SOCKET_BIND:
    /* socket_request(SOCKET_BIND,+domain,+sock_handle,+port,-Error,_,_) 
       Currently only supports AF_INET */
    sock_handle = (SOCKET) ptoc_int(CTXTc 3);
    portnum = (int)ptoc_int(CTXTc 4);
    domain = (int)ptoc_int(CTXTc 2);

    if (!translate_domain(domain, &domain)) {
      return FALSE;
    }
    
    /* Bind server to the agreed upon port number.
    ** See commdef.h for the actual port number. */
    FillWithZeros(socket_addr);
    socket_addr.sin_port = htons((unsigned short)portnum);
    socket_addr.sin_family = AF_INET;
#ifndef WIN_NT
    socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
    
    rc = bind(sock_handle, (PSOCKADDR) &socket_addr, sizeof(socket_addr));
	
    /* error handling */
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_BIND");
    } else
      ecode = SOCK_OK;

    return set_error_code(CTXTc ecode, 5, "SOCKET_BIND");

  case SOCKET_LISTEN: 
    /* socket_request(SOCKET_LISTEN,+sock_handle,+length,-Error,_,_,_) */
    sock_handle = (SOCKET) ptoc_int(CTXTc 2);
    rc = listen(sock_handle, (int)ptoc_int(CTXTc 3));

    /* error handling */
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_LISTEN");
    } else
      ecode = SOCK_OK;

    return set_error_code(CTXTc ecode, 4, "SOCKET_LISTEN");

  case SOCKET_ACCEPT:
    timeout_flag = socket_accept(CTXTc (SOCKET *)&rc, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */ 
      if (BAD_SOCKET(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_ACCEPT");
	sock_handle = rc; /* shut up warning */
      } else {
	sock_handle = rc; /* accept() returns sock_out */
	ecode = SOCK_OK;
      }
	       
      ctop_int(CTXTc 3, (SOCKET) sock_handle);
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_ACCEPT");	  
    }
  case SOCKET_CONNECT: {
    /* socket_request(SOCKET_CONNECT,+domain,+sock_handle,+port,
       +hostname,-Error) */
    timeout_flag = socket_connect(CTXTc &rc, (int)pflags[SYS_TIMER]);

    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 6, "SOCKET_CONNECT");
    } else if (timeout_flag == TIMER_SETUP_ERR) {
      return set_error_code(CTXTc TIMER_SETUP_ERR, 6, "SOCKET_CONNECT");
    } else {
      /* error handling */
      if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_CONNECT");
	/* close, because if connect() fails then socket becomes unusable */
	closesocket(ptoc_int(CTXTc 3));
      } else {
	ecode = SOCK_OK;
      }
      return set_error_code(CTXTc ecode,  6,  "SOCKET_CONNECT");
    }
  }

  case SOCKET_CLOSE: 
    /* socket_request(SOCKET_CLOSE,+sock_handle,-Error,_,_,_,_) */
    
    sock_handle = (SOCKET)ptoc_int(CTXTc 2);
    
    /* error handling */
    rc = closesocket(sock_handle);
    if (SOCKET_OP_FAILED(rc)) {
      ecode = XSB_SOCKET_ERRORCODE;
      perror("SOCKET_CLOSE");
    } else
      ecode = SOCK_OK;
    
    return set_error_code(CTXTc ecode, 3, "SOCKET_CLOSE");
    
  case SOCKET_RECV:
    /* socket_request(SOCKET_RECV,+Sockfd, -Msg, -Error,_,_,_) */
    // TODO: consider adding protection against interrupts, EINTR, like
    //       in socket_get0.
    timeout_flag = socket_recv(CTXTc &rc, &message_buffer, &msg_len, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      switch (rc) {
      case SOCK_OK:
	ecode = SOCK_OK;
	break;
      case SOCK_READMSG_FAILED:
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_RECV");
	break;
      case SOCK_READMSG_EOF:
	ecode = SOCK_EOF;
	break;
      case SOCK_HEADER_LEN_MISMATCH:
	ecode = XSB_SOCKET_ERRORCODE;
	break;
      default:
	xsb_abort("XSB bug: [SOCKET_RECV] invalid return code from readmsg");
      }
	       
      if (message_buffer != NULL) {
	/* use message_buffer+XSB_MSG_HEADER_LENGTH because the first
	   XSB_MSG_HEADER_LENGTH bytes are for the message length header */
	ctop_string(CTXTc 3, (char*)message_buffer+XSB_MSG_HEADER_LENGTH);
	mem_dealloc(message_buffer,msg_len,OTHER_SPACE);
      } else {  /* this happens at the end of a file */
	ctop_string(CTXTc 3, (char*)"");
      }
	       
      return set_error_code(CTXTc ecode, 4, "SOCKET_RECV");  
    }
	       
  case SOCKET_SEND:
    /* socket_request(SOCKET_SEND,+Sockfd, +Msg, -Error,_,_,_) */
    timeout_flag = socket_send(CTXTc &rc, (int)pflags[SYS_TIMER]);
    
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_SEND");
      } else {
	ecode = SOCK_OK;
      }
      return set_error_code(CTXTc ecode,  4,  "SOCKET_SEND"); 
    }

  case SOCKET_GET0:
    /* socket_request(SOCKET_GET0,+Sockfd,-C,-Error,_,_,_) */
    message_buffer = &char_read;
    timeout_flag = socket_get0(CTXTc &rc, message_buffer, (int)pflags[SYS_TIMER]);
	  
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /*error handling */ 
      switch (rc) {
      case 1:
	ctop_int(CTXTc 3,(unsigned char)message_buffer[0]);
	ecode = SOCK_OK;
	break;
      case 0:
	ecode = SOCK_EOF;
	break;
      default:
	ctop_int(CTXTc 3,-1);
	perror("SOCKET_GET0");
	ecode = XSB_SOCKET_ERRORCODE;
      }
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_GET0");
    }    
  case SOCKET_PUT:
    /* socket_request(SOCKET_PUT,+Sockfd,+C,-Error_,_,_) */
    timeout_flag = socket_put(CTXTc &rc, (int)pflags[SYS_TIMER]);
	       
    if (timeout_flag == TIMED_OUT) {
      return set_error_code(CTXTc TIMEOUT_ERR, 4, "SOCKET_SEND");
    } else {
      /* error handling */
      if (rc == 1) {
	ecode = SOCK_OK;
      } else if (SOCKET_OP_FAILED(rc)) {
	ecode = XSB_SOCKET_ERRORCODE;
	perror("SOCKET_PUT");
      }
	       
      return set_error_code(CTXTc ecode,  4,  "SOCKET_PUT");
    }
  case SOCKET_SET_OPTION: {
    /* socket_request(SOCKET_SET_OPTION,+Sockfd,+OptionName,+Value,_,_,_) */
    
    char *option_name = ptoc_string(CTXTc 3);
    
    sock_handle = (SOCKET)ptoc_int(CTXTc 2);

    /* Set the "linger" parameter to a small number of seconds */
    if (0==strcmp(option_name,"linger")) {
      int  linger_time=(int)ptoc_int(CTXTc 4);
      
      if (linger_time < 0) {
	sock_linger_opt.l_onoff = FALSE;
	sock_linger_opt.l_linger = 0;
      } else {
	sock_linger_opt.l_onoff = TRUE;
	sock_linger_opt.l_linger = linger_time;
      }
      
      if (SETSOCKOPT(sock_handle, SOL_SOCKET, SO_LINGER,
		     &sock_linger_opt, sizeof(sock_linger_opt))
	  < 0) {
	xsb_warn(CTXTc "[SOCKET_SET_OPTION] Cannot set socket linger time");
	return FALSE;
      } 
    }else {
      xsb_warn(CTXTc "[SOCKET_SET_OPTION] Invalid option, `%s'", option_name);
      return FALSE;
    }
    
    return TRUE;
  }

  case SOCKET_SET_SELECT:  {  
    /*socket_request(SOCKET_SET_SELECT,+connection_name,
      +R_sockfd,+W_sockfd,+E_sockfd) */
    prolog_term R_sockfd, W_sockfd, E_sockfd;
    int i, connection_count;
    int rmax_fd=0, wmax_fd=0, emax_fd=0; 
    char *connection_name = ptoc_string(CTXTc 2);
    
    /* bind fds to input arguments */
    R_sockfd = reg_term(CTXTc 3);
    W_sockfd = reg_term(CTXTc 4);
    E_sockfd = reg_term(CTXTc 5);	
    
    /* initialize the array of connect_t structure for select call */	
    init_connections(CTXT); 
    
    SYS_MUTEX_LOCK(MUTEX_SOCKETS);
    /* check whether the same connection name exists */
    for (i=0;i<MAXCONNECT;i++) {
      if ((connections[i].empty_flag==FALSE) &&
	  (strcmp(connection_name,connections[i].connection_name)==0)) 	
	xsb_abort("[SOCKET_SET_SELECT] Connection `%s' already exists!",
		  connection_name);
    }
    
    /* check whether there is empty slot left for connection */	
    if ((connection_count=checkslot())<MAXCONNECT) {
      if (connections[connection_count].connection_name == NULL) {
	connections[connection_count].connection_name = connection_name;
	connections[connection_count].empty_flag = FALSE;
	
	/* call the utility function separately to take the fds in */
	list_sockfd(R_sockfd, &connections[connection_count].readset,
		    &rmax_fd, &connections[connection_count].read_fds,
		    &connections[connection_count].sizer);
	list_sockfd(W_sockfd, &connections[connection_count].writeset,
		    &wmax_fd, &connections[connection_count].write_fds,
		    &connections[connection_count].sizew);
	list_sockfd(E_sockfd, &connections[connection_count].exceptionset, 
		    &emax_fd,&connections[connection_count].exception_fds,
		    &connections[connection_count].sizee);
	
	connections[connection_count].maximum_fd =
	  xsb_max(xsb_max(rmax_fd,wmax_fd), emax_fd);
      } else 
	/* if this one is reached, it is probably a bug */
	xsb_abort("[SOCKET_SET_SELECT] All connections are busy!");
    } else
      xsb_abort("[SOCKET_SET_SELECT] Max number of collections exceeded!");
    SYS_MUTEX_UNLOCK(MUTEX_SOCKETS);
    
    return TRUE;
  }
  
  case SOCKET_SELECT: {
    /* socket_request(SOCKET_SELECT,+connection_name, +timeout
       -avail_rsockfds,-avail_wsockfds,
       -avail_esockfds,-ecode)
       Returns 3 prolog_terms for available socket fds */

    prolog_term Avail_rsockfds, Avail_wsockfds, Avail_esockfds;
    prolog_term Avail_rsockfds_tail, Avail_wsockfds_tail, Avail_esockfds_tail;

    int maxfd;
    int i;       /* index for connection_count */
    char *connection_name = ptoc_string(CTXTc 2);
    struct timeval *tv;
    prolog_term timeout_term;
    int timeout =0;
    int connectname_found = FALSE;
    int count=0;			

    SYS_MUTEX_LOCK(MUTEX_SOCKETS);
    /* specify the time out */
    timeout_term = reg_term(CTXTc 3);
    if (isointeger(timeout_term)) {
      timeout = (int)oint_val(timeout_term);
      /* initialize tv */
      tv = (struct timeval *)mem_alloc(sizeof(struct timeval),LEAK_SPACE);
      tv->tv_sec = timeout;
      tv->tv_usec = 0;
    } else
      tv = NULL; /* no timeouts */

    /* initialize the prolog term */ 
    Avail_rsockfds = p2p_new(CTXT);
    Avail_wsockfds = p2p_new(CTXT);
    Avail_esockfds = p2p_new(CTXT); 

    /* bind to output arguments */
    Avail_rsockfds = reg_term(CTXTc 4);
    Avail_wsockfds = reg_term(CTXTc 5);
    Avail_esockfds = reg_term(CTXTc 6);

    Avail_rsockfds_tail = Avail_rsockfds;
    Avail_wsockfds_tail = Avail_wsockfds;
    Avail_esockfds_tail = Avail_esockfds;

    /*
      // This was wrong. Lists are now made inside test_ready()
      c2p_list(CTXTc Avail_rsockfds_tail);
      c2p_list(CTXTc Avail_wsockfds_tail);	
      c2p_list(CTXTc Avail_esockfds_tail); 
    */
    
    for (i=0; i < MAXCONNECT; i++) {
      /* find the matching connection_name to select */
      if(connections[i].empty_flag==FALSE) {
	if (strcmp(connection_name, connections[i].connection_name) == 0) {
	  connectname_found = TRUE;
	  count = i;
	  break;
	} 
      }
    }
    if( i >= MAXCONNECT )  /* if no matching connection_name */
      xsb_abort("[SOCKET_SELECT] connection `%s' doesn't exist",
		connection_name); 
    
    /* compute maxfd for select call */
    maxfd = connections[count].maximum_fd + 1;

    /* FD_SET all sockets */
    set_sockfd( CTXTc count );

    /* test whether the socket fd is available */
    rc = select(maxfd, &connections[count].readset, 
		&connections[count].writeset,
		&connections[count].exceptionset, tv);
    
    /* error handling */	
    if (rc == 0)     /* timed out */
      ecode = TIMEOUT_ERR;
    else if (SOCKET_OP_FAILED(rc)) {
      perror("SOCKET_SELECT");
      ecode = XSB_SOCKET_ERRORCODE;
    } else {      /* no error */
      ecode = SOCK_OK;
	 
      /* call the utility function to return the available socket fds */
      test_ready(CTXTc &Avail_rsockfds_tail, &connections[count].readset,
		 connections[count].read_fds,connections[count].sizer);

      test_ready(CTXTc &Avail_wsockfds_tail, &connections[count].writeset,
		 connections[count].write_fds,connections[count].sizew);

      test_ready(CTXTc &Avail_esockfds_tail,&connections[count].exceptionset,
		 connections[count].exception_fds,connections[count].sizee);
    }
    SYS_MUTEX_UNLOCK(MUTEX_SOCKETS);

    if (tv) mem_dealloc((struct timeval *)tv,sizeof(struct timeval),LEAK_SPACE);
    SQUASH_LINUX_COMPILER_WARN(connectname_found) ; 
    return set_error_code(CTXTc ecode, 7, "SOCKET_SELECT");
  }

  case SOCKET_SELECT_DESTROY:  { 
    /*socket_request(SOCKET_SELECT_DESTROY, +connection_name) */
    char *connection_name = ptoc_string(CTXTc 2);
    select_destroy(CTXTc connection_name);
    return TRUE;
  }

  default:
    xsb_warn(CTXTc "[SOCKET_REQUEST] Invalid socket request %d", (int) ptoc_int(CTXTc 1));
    return FALSE;
  }

  /* This trick would report a bug, if a newly added case
     doesn't have a return clause */
  xsb_bug("SOCKET_REQUEST case %d has no return clause", ptoc_int(CTXTc 1));
}
Example #18
0
int gc_heap(CTXTdeclc int arity, int ifStringGC)
{
#ifdef GC
  CPtr p;
  double  begin_marktime, end_marktime,
    end_slidetime, end_copy_time,
    begin_stringtime, end_stringtime;
  size_t  marked = 0, marked_dregs = 0, i;
  int ii;
  size_t  start_heap_size;
  size_t  rnum_in_trieinstr_unif_stk = (trieinstr_unif_stkptr-trieinstr_unif_stk)+1;
  DECL_GC_PROFILE;
  garbage_collecting = 1;  // flag for profiling that we are gc-ing

  //  printf("start gc(%ld): e:%p,h:%p,hf:%p\n",(long)(cpu_time()*1000),ereg,hreg,hfreg);
  INIT_GC_PROFILE;
  if (pflags[GARBAGE_COLLECT] != NO_GC) {
    num_gc++ ;
    GC_PROFILE_PRE_REPORT;
    slide = (pflags[GARBAGE_COLLECT] == SLIDING_GC) | 
      (pflags[GARBAGE_COLLECT] == INDIRECTION_SLIDE_GC);
    
    if (fragmentation_only) 
      slide = FALSE;
    heap_early_reset = ls_early_reset = 0;
    
    GC_PROFILE_START_SUMMARY;
    
    begin_marktime = cpu_time();
    start_heap_size = hreg+1-(CPtr)glstack.low;
    
    /* make sure the top choice point heap pointer 
       that might not point into heap, does */
    if (hreg == cp_hreg(breg)) {
      *hreg = makeint(666) ;
      hreg++;
    }
#ifdef SLG_GC
    /* same for the freeze heap pointer */
    if (hfreg == hreg && hreg == cp_hreg(bfreg)) {
      *hreg = makeint(66600);
      hreg++;
    }
#endif
    
    /* copy the aregs to the top of the heap - only if sliding */
    /* just hope there is enough space */
    /* this happens best before the stack_boundaries are computed */
    if (slide) {
      if (delayreg != NULL) {
	arity++;
	reg[arity] = (Cell)delayreg;
      }
      for (ii = 1; ii <= arity; ii++) {
	//	printf("reg[%d] to heap: %lx\n",ii,(size_t)reg[i]);
	*hreg = reg[ii];
	hreg++;
      }
      arity += (int)rnum_in_trieinstr_unif_stk;
      for (i = 0; i < rnum_in_trieinstr_unif_stk; i++) {
	//	printf("trieinstr_unif_stk[%d] to heap: %lx\n",i,(size_t)trieinstr_unif_stk[i]);
	*hreg = trieinstr_unif_stk[i];
	hreg++;
      }
      //      printf("extended heap: hreg=%p, arity=%d, rnum_in=%d\n",hreg,arity, rnum_in_trieinstr_unif_stk);
#ifdef SLG_GC
      /* in SLGWAM, copy hfreg to the heap */
      //      printf("hfreg to heap is %p at %p, rnum_in_trieinstr_unif_stk=%d,arity=%d,delay=%p\n",hfreg,hreg,rnum_in_trieinstr_unif_stk,arity,delayreg);
      *(hreg++) = (Cell) hfreg;
#endif
    }

    if (top_of_localstk < hreg) {
      fprintf(stderr,"stack clobbered: no space for gc_heap\n"); 
      xsb_exit( "stack clobbered");
    }

    gc_strings = ifStringGC; /* default */
    gc_strings = should_gc_strings();  // collect strings for any reason?
    marked = mark_heap(CTXTc arity, &marked_dregs);
    
    end_marktime = cpu_time();
    
    if (fragmentation_only) {
      /* fragmentation is expressed as ratio not-marked/total heap in use
	 this is internal fragmentation only.  we print marked and total,
	 so that postprocessing can do what it wants with this info. */
      xsb_dbgmsg((LOG_GC, "marked_used_missed(%d,%d,%d,%d).",
		 marked,hreg+1-(CPtr)glstack.low,
		 heap_early_reset,ls_early_reset));

    free_marks:

#ifdef PRE_IMAGE_TRAIL
      /* re-tag pre image cells in trail */
      for (p = tr_bot; p <= tr_top ; p++ ) {
	if (tr_pre_marked(p-tr_bot)) {
	  *p = *p | PRE_IMAGE_MARK;
	  tr_clear_pre_mark(p-tr_bot);
	}
      }
#endif

      /* get rid of the marking areas - if they exist */
      if (heap_marks)  { mem_dealloc((heap_marks-1),heap_marks_size,GC_SPACE); heap_marks = NULL; }
      if (tr_marks)    { mem_dealloc(tr_marks,tr_top-tr_bot+1,GC_SPACE); tr_marks = NULL; }
      if (ls_marks)    { mem_dealloc(ls_marks,ls_bot - ls_top + 1,GC_SPACE); ls_marks = NULL; }
      if (cp_marks)    { mem_dealloc(cp_marks,cp_bot - cp_top + 1,GC_SPACE); cp_marks = NULL; }
      if (slide_buf)   { mem_dealloc(slide_buf,(slide_buf_size+1)*sizeof(CPtr),GC_SPACE); slide_buf = NULL; }
      goto end;
    }
    
    GC_PROFILE_MARK_SUMMARY;
    
    /* An attempt to add some gc/expansion policy;
       ideally this should be user-controlled */
#if (! defined(GC_TEST))
    if (marked > ((hreg+1-(CPtr)glstack.low)*mark_threshold))
      {
	GC_PROFILE_QUIT_MSG;
        if (slide)
          hreg -= arity;
	total_time_gc += (double) 
	  (end_marktime-begin_marktime);
        goto free_marks; /* clean-up temp areas and get out of here... */
      }
#endif
    
    total_collected += (start_heap_size - marked);

    if (slide)
      {
	GC_PROFILE_SLIDE_START_TIME;
	hreg = slide_heap(CTXTc marked) ;

#ifdef DEBUG_VERBOSE
	if (hreg != (heap_bot+marked))
	  xsb_dbgmsg((LOG_GC, "heap sliding gc - inconsistent hreg"));
#endif

#ifdef SLG_GC
	/* copy hfreg back from the heap */
	hreg--;
	hfreg = (CPtr) *hreg;
#endif

	/* copy the aregs from the top of the heap back */
	hreg -= arity;
	hbreg = cp_hreg(breg);
	
	p = hreg;
	
	arity -= (int)rnum_in_trieinstr_unif_stk;
	for (ii = 1; ii <= arity; ii++) {
	  reg[ii] = *p++;
	  //	  printf("heap to reg[%d]: %lx\n",ii,(size_t)reg[i]);
	}
	if (delayreg != NULL)
	  delayreg = (CPtr)reg[arity--];
	for (i = 0; i < rnum_in_trieinstr_unif_stk; i++) {
	  trieinstr_unif_stk[i] = *p++;
	  //	  printf("heap to trieinstr_unif_stk[%d]: %lx\n",i,(size_t)trieinstr_unif_stk[i]);
	}

	end_slidetime = cpu_time();
	
	total_time_gc += (double) 
	  (end_slidetime - begin_marktime);
	
	GC_PROFILE_SLIDE_FINAL_SUMMARY;
      }
    else
      { /* else we call the copying collector a la Cheney */
	CPtr begin_new_heap, end_new_heap;
	
	GC_PROFILE_COPY_START_TIME;
	
	begin_new_heap = (CPtr)mem_alloc(marked*sizeof(Cell),GC_SPACE);
	if (begin_new_heap == NULL)
	  xsb_exit( "copying garbage collection could not allocate new heap");
	end_new_heap = begin_new_heap+marked;

	hreg = copy_heap(CTXTc marked,begin_new_heap,end_new_heap,arity);

	mem_dealloc(begin_new_heap,marked*sizeof(Cell),GC_SPACE);
	adapt_hfreg_from_choicepoints(CTXTc hreg);
	hbreg = cp_hreg(breg);

#ifdef SLG_GC
	hfreg = hreg;
#endif
	end_copy_time = cpu_time();
	
	total_time_gc += (double) 
	  (end_copy_time - begin_marktime);
	
	GC_PROFILE_COPY_FINAL_SUMMARY;
      }
    
    if (print_on_gc) print_all_stacks(CTXTc arity);
    
    /* get rid of the marking areas - if they exist */
    if (heap_marks)  { 
      check_zero(heap_marks,(heap_top - heap_bot),"heap") ;
      mem_dealloc((heap_marks-1),heap_marks_size,GC_SPACE) ; /* see its calloc */
      heap_marks = NULL ;
    }
    if (tr_marks)    { 
      check_zero(tr_marks,(tr_top - tr_bot + 1),"tr") ;
      mem_dealloc(tr_marks,tr_top-tr_bot+1,GC_SPACE) ;
      tr_marks = NULL ;
    }
    if (ls_marks)    { 
      check_zero(ls_marks,(ls_bot - ls_top + 1),"ls") ;
      mem_dealloc(ls_marks,ls_bot - ls_top + 1,GC_SPACE) ;
      ls_marks = NULL ;
    }
    if (cp_marks)    {  
      check_zero(cp_marks,(cp_bot - cp_top + 1),"cp") ;
      mem_dealloc(cp_marks,cp_bot - cp_top + 1,GC_SPACE) ;
      cp_marks = NULL ;
    }
    if (slide_buf)   { 
      mem_dealloc(slide_buf,(slide_buf_size+1)*sizeof(CPtr),GC_SPACE); 
      slide_buf = NULL; 
    }
#ifdef SAFE_GC
    p = hreg;
    while (p < heap_top)
      *p++ = 0;
#endif
    
  } /* if (pflags[GARBAGE_COLLECT]) */
#else
  /* for no-GC, there is no gc, but stack expansion can be done */
#endif
  
#ifdef GC
 end:
  
  /*************** GC STRING-TABLE (already marked from heap) *******************/
#ifndef NO_STRING_GC
#ifdef MULTI_THREAD
  if (flags[NUM_THREADS] == 1) {
#endif
    if (gc_strings && (flags[STRING_GARBAGE_COLLECT] == 1)) {
      num_sgc++;
      begin_stringtime = cpu_time();
      mark_nonheap_strings(CTXT);
      free_unused_strings();
      //      printf("String GC reclaimed: %d bytes\n",beg_string_space_size - pspacesize[STRING_SPACE]);
      gc_strings = FALSE;
      end_stringtime = cpu_time();
      total_time_gc += end_stringtime - begin_stringtime;
    }
    /* update these even if no GC, to avoid too many calls just to gc strings */
    last_string_space_size = pspacesize[STRING_SPACE];
    last_assert_space_size = pspacesize[ASSERT_SPACE];
    force_string_gc = FALSE;
#ifdef MULTI_THREAD
  }
#endif
#endif /* ndef NO_STRING_GC */

  GC_PROFILE_POST_REPORT;
  garbage_collecting = 0;
  
#endif /* GC */
  //  printf("   end gc(%ld), hf:%p,h:%p, space=%d\n",(long)(cpu_time()*1000),hfreg,hreg,(pb)top_of_localstk - (pb)top_of_heap);

  return(TRUE);

} /* gc_heap */
Example #19
0
int sys_syscall(CTXTdeclc int callno)
{
  int result=-1;
  struct stat stat_buff;

  switch (callno) {
  case SYS_exit: {
    int exit_code;
    exit_code = (int)ptoc_int(CTXTc 3);
    xsb_error("\nXSB exited with exit code: %d", exit_code);
    exit(exit_code); break;
  }
  case SYS_getpid :
#ifndef WIN_NT
    result = getpid();
#else
    result = _getpid();
#endif
    break; 
#if (!defined(WIN_NT))
  case SYS_link  :
    result = link(ptoc_longstring(CTXTc 3), ptoc_longstring(CTXTc 4));
    break;
#endif
  case SYS_mkdir: {
#ifndef WIN_NT
    /* create using mode 700 */
    result = mkdir(ptoc_longstring(CTXTc 3), 0700); 
#else
    result = _mkdir(ptoc_longstring(CTXTc 3)); 
#endif
    break;
  }
  case SYS_rmdir: {
#ifndef WIN_NT
    result = rmdir(ptoc_longstring(CTXTc 3)); 
#else
    result = _rmdir(ptoc_longstring(CTXTc 3)); 
#endif
    break;
  }
  case SYS_unlink: result = unlink(ptoc_longstring(CTXTc 3)); break;
  case SYS_chdir : result = chdir(ptoc_longstring(CTXTc 3)); break;
  case SYS_access: {
    switch(*ptoc_string(CTXTc 4)) {
    case 'r': /* read permission */
      result = access(ptoc_longstring(CTXTc 3), R_OK_XSB);
      break;
    case 'w': /* write permission */
      result = access(ptoc_longstring(CTXTc 3), W_OK_XSB);
      break;
    case 'x': /* execute permission */
      result = access(ptoc_longstring(CTXTc 3), X_OK_XSB);
      break;
    default:
      result = -1;
    }
    break;
  }
  case SYS_stat  : {
    /* Who put this in??? What did s/he expect to get out of this call?
       stat_buff is never returned (and what do you do with it in Prolog?)!!!
    */
    result = stat(ptoc_longstring(CTXTc 3), &stat_buff);
    break;
  }
  case SYS_rename: 
    result = rename(ptoc_longstring(CTXTc 3), ptoc_longstring(CTXTc 4)); 
    break;
  case SYS_cwd: {
    char current_dir[MAX_CMD_LEN];
    /* returns 0, if != NULL, 1 otherwise */
    result = (getcwd(current_dir, MAX_CMD_LEN-1) == NULL);
    if (result == 0)
      ctop_string(CTXTc 3,current_dir);
    break;
  }
  case SYS_filecopy: {
    char *from = ptoc_longstring(CTXTc 3);
    char *to = ptoc_longstring(CTXTc 4);
    result = (file_copy(CTXTc from,to,"w") == 0);
    break;
  }
  case SYS_fileappend: {
    char *from = ptoc_longstring(CTXTc 3);
    char *to = ptoc_longstring(CTXTc 4);
    result = (file_copy(CTXTc from,to,"a") == 0);
    break;
  }
  case SYS_create: {
    result = open(ptoc_longstring(CTXTc 3),O_CREAT|O_EXCL,S_IREAD|S_IWRITE);
    if (result >= 0) close(result);
    break;
  }
  case SYS_readlink: {
    char *inpath = ptoc_longstring(CTXTc 3);
    //    char *outpath = file_readlink(CTXTc inpath);
    char *outpath = file_readlink(inpath);
    if (outpath == NULL) {
      // memory for this case is dealocated in file_readlink in pathname_xsb.c
      result = -1;
    } else {
      ctop_string(CTXTc 4,outpath);
      mem_dealloc(outpath,MAXPATHLEN,OTHER_SPACE);
      result = 0;
    }
    break;
  }
  case SYS_realpath: {
    char *inpath = ptoc_longstring(CTXTc 3);
    char *outpath = file_realpath(inpath);
    if (outpath == NULL) {
      // memory for this case is dealocated in file_readlink in pathname_xsb.c
      result = -1;
    } else {
      ctop_string(CTXTc 4,outpath);
      mem_dealloc(outpath,MAXPATHLEN,OTHER_SPACE);
      result = 0;
    }
    break;
  }

  case STATISTICS_2: {
    get_statistics(CTXT);
    break;
  }
  case SYS_epoch_seconds: {
    ctop_int(CTXTc 3,(Integer)time(0));
    break;
  }
  case SYS_epoch_msecs: {
    static struct timeb time_epoch;
    ftime(&time_epoch);
    ctop_int(CTXTc 3,(Integer)(time_epoch.time));
    ctop_int(CTXTc 4,(Integer)(time_epoch.millitm));
    break;
  }
  case SYS_main_memory_size: {
    size_t memory_size = getMemorySize();
    ctop_int(CTXTc 3,(UInteger)memory_size);
    break;
  }
  default: xsb_abort("[SYS_SYSCALL] Unknown system call number, %d", callno);
  }
  return result;
}
/* the following function is a general format for timeout control. it takes 
   function calls which need timeout control as argument and controls the
   timeout for different platform */ 
int make_timed_call(CTXTdeclc xsbTimeout *pptr,  void (*fptr)(xsbTimeout *))
{
#if defined(WIN_NT) || defined(MULTI_THREAD)   
  int return_msg; /* message_pump() return value */
#endif

#ifdef MULTI_THREAD /* USE PTHREADS */

#ifdef WIN_NT
  pptr->timeout_info.timedThread = mem_alloc(sizeof(pthread_t),LEAK_SPACE);
#define TIMED_THREAD_CREATE_ARG pptr->timeout_info.timedThread
#else
#define TIMED_THREAD_CREATE_ARG &pptr->timeout_info.timedThread
#endif
  pptr->timeout_info.th=th;
  // below, fptr is pointer to start routine, pptr is pointer to arg-array.
  // TIMED_THREAD_CREATE_ARG is a cell of timeout_info.
  if (pthread_create(TIMED_THREAD_CREATE_ARG, NULL, fptr, pptr)) {
    xsb_error("SOCKET_REQUEST: Can't create concurrent timer thread\n");
    return TIMER_SETUP_ERR;
  }
  PTHREAD_DETACH(pptr->timeout_info.timedThread);
  return_msg = OP_TIMED_OUT(pptr);
#ifdef WIN_NT
  mem_dealloc(pptr->timeout_info.timedThread,sizeof(pthread_t),LEAK_SPACE);
#endif
  if (return_msg == TIMER_SETUP_ERR) {
    return TIMER_SETUP_ERR;  
  } else if (!return_msg) { /* no timeout */
    TURNOFFALARM;
    return FALSE;
  } else { /* timeout */
    TURNOFFALARM;
    return TRUE;
  }

#else /* not multithreaded */

#ifdef WIN_NT
  /* create a concurrent timed thread; 
     pptr points to the procedure to be timed */  
  pptr->timeout_info.parent_thread = (Integer)GetCurrentThreadId();
  if((timedThread = _beginthread((void *)fptr,0,(void*)(pptr)))==-1) { 
    xsb_error("SOCKET_REQUEST: Can't create concurrent timer thread\n");
    return TIMER_SETUP_ERR;
  }
  return_msg = OP_TIMED_OUT(pptr);
  /* OP_TIMED_OUT returns TRUE/FALSE/TIMER_SETUP_ERR */
  if (return_msg == TIMER_SETUP_ERR) {
    return TIMER_SETUP_ERR;  
  } else if (!return_msg) { /* no timeout */
    TURNOFFALARM;
    return FALSE;
  } else { /* timeout */
    TURNOFFALARM;
    return TRUE;
  }
#else /* UNIX */
  SETALARM;     /* specify the timer handler in Unix;
		   Noop in Windows (done in SetTimer) */

  if ( !OP_TIMED_OUT ) { /* no timeout */
    SET_TIMER; /* specify the timeout period */       
    (*fptr)(CTXTc pptr); /* procedure call that needs timeout control */
    TURNOFFALARM;
    return FALSE;
  } else {  /* timeout */
    TURNOFFALARM;
    return TRUE;
  }

#endif

#endif

}