Exemplo n.º 1
0
int
attribute_hidden
__pthread_enable_asynccancel (void)
{
  struct pthread *self = THREAD_SELF;
  int oldval;
  if (is_recording()) {
    pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
    oldval = THREAD_GETMEM (self, cancelhandling);
    pthread_log_record (oldval, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
  } else if (is_replaying()) {
    pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
    oldval = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
  } else {
    oldval = THREAD_GETMEM (self, cancelhandling);
  }

  while (1)
    {
      int newval = oldval | CANCELTYPE_BITMASK;

      if (newval == oldval)
	break;

      int curval;
      if (is_recording()) {
	pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
	curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, oldval);
	pthread_log_record (curval, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
      } else if (is_replaying()) {
	pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
	curval = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
      } else {
	curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, oldval);
      }
 
      if (__builtin_expect (curval == oldval, 1))
	{
	  if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
	    {
	      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
	      __do_cancel ();
	    }

	  break;
	}

      /* Prepare the next round.  */
      oldval = curval;
    }

  return oldval;
}
Exemplo n.º 2
0
void
__cleanup_fct_attribute
__pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
{
  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
  struct pthread *self = THREAD_SELF;

  /* Store old info.  */
  ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
  ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);

  int cancelhandling;
  if (is_recording()) {
    pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
    cancelhandling = THREAD_GETMEM (self, cancelhandling);
    pthread_log_record (cancelhandling, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
  } else if (is_replaying()) {
    pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
    cancelhandling = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
  } else {
    cancelhandling = THREAD_GETMEM (self, cancelhandling);
  }
  /* Disable asynchronous cancellation for now.  */
  if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
    while (1)
      {
	int curval;
	if (is_recording()) {
	  pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
	  curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, cancelhandling & ~CANCELTYPE_BITMASK, cancelhandling);
	  pthread_log_record (curval, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
	} else if (is_replaying()) {
	  pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
	  curval = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
	} else {
	  curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, cancelhandling & ~CANCELTYPE_BITMASK, cancelhandling);
	}
	if (__builtin_expect (curval == cancelhandling, 1))
	  /* Successfully replaced the value.  */
	  break;

	/* Prepare for the next round.  */
	cancelhandling = curval;
      }

  ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
				? PTHREAD_CANCEL_ASYNCHRONOUS
				: PTHREAD_CANCEL_DEFERRED);

  /* Store the new cleanup handler info.  */
  THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
}
Exemplo n.º 3
0
static ssize_t scribe_do_write(struct file *file, const char __user *buf,
			       ssize_t count, loff_t *ppos)
{
	struct scribe_ps *scribe = current->scribe;
	int force_block = 0;
	ssize_t ret;

	if (!is_scribed(scribe))
		return do_write(file, buf, count, ppos, force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		count = scribe->orig_ret;
		if (count <= 0)
			return count;
		force_block = 1;
	}

out:
	scribe->in_read_write = true;
	ret = do_write(file, buf, count, ppos, force_block);
	scribe->in_read_write = false;

	return ret;
}
Exemplo n.º 4
0
void
__cleanup_fct_attribute
__pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
{
  struct pthread *self = THREAD_SELF;
  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;

  THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);

  int cancelhandling;
  if (is_recording()) {
    pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
    cancelhandling = THREAD_GETMEM (self, cancelhandling);
    pthread_log_record (cancelhandling, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
  } else if (is_replaying()) {
    pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
    cancelhandling = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
  } else {
    cancelhandling = THREAD_GETMEM (self, cancelhandling);
  }
  if (ibuf->priv.data.canceltype != PTHREAD_CANCEL_DEFERRED && (cancelhandling & CANCELTYPE_BITMASK) == 0)
    {
      while (1)
	{
	  int curval;
	  if (is_recording()) {
	    pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
	    curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, cancelhandling | CANCELTYPE_BITMASK, cancelhandling);
	    pthread_log_record (curval, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
	  } else if (is_replaying()) {
	    pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
	    curval = pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
	  } else {
	    curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, cancelhandling | CANCELTYPE_BITMASK, cancelhandling);
	  }
	  if (__builtin_expect (curval == cancelhandling, 1))
	    /* Successfully replaced the value.  */
	    break;

	  /* Prepare for the next round.  */
	  cancelhandling = curval;
	}

      CANCELLATION_P (self);
    }
}
Exemplo n.º 5
0
static int scribe_recvmsg(struct kiocb *iocb, struct socket *sock,
			  struct msghdr *m, size_t total_len,
			  int flags)
{
	struct scribe_ps *scribe = current->scribe;
	int ret, err;

	if (scribe_is_deterministic(sock) || !is_scribed(scribe)) {
		if (is_replaying(scribe)) {
			flags &= ~MSG_DONTWAIT;
			flags |= MSG_WAITALL;

			if (!scribe_is_in_read_write(scribe))
				total_len = scribe->orig_ret;
			if ((ssize_t)total_len <= 0)
				return total_len;
		}
		scribe_data_det();
		ret = sock->real_ops->recvmsg(iocb, sock, m, total_len, flags),
		scribe_data_pop_flags();
		return ret;
	}

	scribe_data_non_det_need_info();

	err = scribe_result_cond(
		ret, sock->real_ops->recvmsg(iocb, sock, m, total_len, flags),
		!scribe_is_in_read_write(scribe) || ret > 0);
	if (err)
		goto out;
	if (ret <= 0)
		goto out;

	if (is_replaying(scribe))
		scribe_emul_copy_to_user(scribe, NULL, INT_MAX);

	err = scribe_value(&m->msg_namelen);
	if (err)
		goto out;
	err = scribe_buffer(m->msg_name, m->msg_namelen);

out:
	scribe_data_pop_flags();
	return err ?: ret;
}
Exemplo n.º 6
0
static int scribe_sendmsg(struct kiocb *iocb, struct socket *sock,
			  struct msghdr *m, size_t total_len)
{
	struct scribe_ps *scribe = current->scribe;
	int ret, err;

	if (scribe_is_deterministic(sock) || !is_scribed(scribe)) {
		if (is_replaying(scribe)) {
			m->msg_flags &= ~MSG_DONTWAIT;

			if (!scribe_is_in_read_write(scribe))
				total_len = scribe->orig_ret;
			if ((ssize_t)total_len <= 0)
				return total_len;
		}
		ret = sock->real_ops->sendmsg(iocb, sock, m, total_len);
		return ret;
	}

	scribe_data_need_info();

	err = scribe_result_cond(
		ret, sock->real_ops->sendmsg(iocb, sock, m, total_len),
		!scribe_is_in_read_write(scribe) || ret > 0);
	if (err)
		goto out;
	if (ret <= 0)
		goto out;

	if (is_replaying(scribe))
		scribe_emul_copy_from_user(scribe, NULL, INT_MAX);

out:
	scribe_data_pop_flags();
	return err ?: ret;
}
Exemplo n.º 7
0
// REPLAY: The above function only modifies cancelhandling
void
internal_function attribute_hidden
__pthread_disable_asynccancel (int oldtype)
{
  if (is_recording()) {
    struct pthread *self = THREAD_SELF;
    pthread_log_record (0, PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling, 1); 
    __internal_pthread_disable_asynccancel(oldtype);
    pthread_log_record (0, PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling, 0); 
  } else if (is_replaying()) {
    struct pthread *self = THREAD_SELF;
    pthread_log_replay (PTHREAD_CANCELHANDLING_ENTER, (u_long) &self->cancelhandling); 
    pthread_log_replay (PTHREAD_CANCELHANDLING_EXIT, (u_long) &self->cancelhandling); 
  } else {
    __internal_pthread_disable_asynccancel(oldtype);
  }
}
Exemplo n.º 8
0
bool DetCheckTraceBuilder::cond_branch(bool cnd){
  if(is_replaying()){
    assert(cond_branch_log_index < cond_branch_log.size());
    bool logged = cond_branch_log[cond_branch_log_index];
    ++cond_branch_log_index;
    if(logged != cnd){
      nondeterminism_error("Branch condition value changed in replay.");
      return false;
    }
  }else{
    if(cond_branch_log_index < cond_branch_log.size()){
      cond_branch_log[cond_branch_log_index] = cnd;
    }else{
      assert(cond_branch_log_index == cond_branch_log.size());
      cond_branch_log.push_back(cnd);
    }
    ++cond_branch_log_index;
  }
  return true;
}
Exemplo n.º 9
0
static ssize_t scribe_do_read(struct file *file, char __user *buf,
			      ssize_t len, loff_t *ppos)
{
	struct scribe_ps *scribe = current->scribe;
	int force_block = 0;
	ssize_t ret;

	if (!is_scribed(scribe))
		return do_read(file, buf, len, ppos, force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		len = scribe->orig_ret;
		if (len <= 0)
			return len;
		force_block = 1;
	}

	if (is_deterministic(file))
		goto out;

	scribe_data_non_det();

	if (is_recording(scribe))
		goto out;

	return scribe_emul_copy_to_user(scribe, buf, len);

out:
	scribe->in_read_write = true;
	ret = do_read(file, buf, len, ppos, force_block);
	scribe->in_read_write = false;
	return ret;
}
Exemplo n.º 10
0
static int scribe_getsockopt(struct socket *sock, int level,
			     int optname, char __user *optval,
			     int __user *optlen)
{
	struct scribe_ps *scribe = current->scribe;
	int ret, err;

	scribe_data_non_det_need_info();

	err = scribe_result(
		ret, sock->real_ops->getsockopt(sock, level, optname,
						optval, optlen));
	if (err)
		return err;
	if (ret < 0)
		return ret;

	if (is_replaying(scribe))
		scribe_emul_copy_to_user(scribe, NULL, INT_MAX);
	return ret;
}
Exemplo n.º 11
0
static ssize_t scribe_do_readv_writev(int type, struct file *file,
				      const struct iovec __user * uvector,
				      unsigned long nr_segs, loff_t *pos)
{
	struct scribe_ps *scribe = current->scribe;
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	int force_block = 0;
	ssize_t ret, len = 0;

	if (!is_scribed(scribe))
		return do_readv_writev(type, file, uvector, nr_segs, 0, pos,
				       force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		len = scribe->orig_ret;
		if (len <= 0) {
			rw_copy_check_uvector(type, uvector, nr_segs,
					      ARRAY_SIZE(iovstack), iovstack,
					      &iov);
			ret = len;
			goto free;
		}
		force_block = 1;
	}

	if (type == READ) {
		if (is_deterministic(file))
			goto out;

		scribe_data_non_det();

		if (is_recording(scribe))
			goto out;

		rw_copy_check_uvector(type, uvector, nr_segs,
				      ARRAY_SIZE(iovstack), iovstack, &iov);

		ret =  __do_loop_readv_writev(file, iov, nr_segs, len, pos,
					      io_scribe_emul_copy_to_user);
		goto free;
	}

out:
	scribe->in_read_write = true;
	ret = do_readv_writev(type, file, uvector, nr_segs, len, pos,
			      force_block);
	scribe->in_read_write = false;
free:
	if (iov != iovstack)
		kfree(iov);
	return ret;
}