int main(int argc, char **argv)
{
	int i;

	int64_t p1 = 0;
	uint64_t p2 = 0;
	int32_t p3 = 0;
	uint32_t p4 = 0;
	int16_t p5 = 0;
	uint16_t p6 = 0;
	int8_t p7 = 0;
	uint16_t p8 = 0;

	atomic_store_int64_t(&p1, 55);
	atomic_store_uint64_t(&p2, 55);
	atomic_store_int32_t(&p3, 55);
	atomic_store_uint32_t(&p4, 55);
	atomic_store_int16_t(&p5, 55);
	atomic_store_uint16_t(&p6, 55);
	atomic_store_int8_t(&p7, 55);
	atomic_store_uint8_t(&p8, 55);

	assert(p1 == 55);
	assert(p2 == 55);
	assert(p3 == 55);
	assert(p4 == 55);
	assert(p5 == 55);
	assert(p6 == 55);
	assert(p7 == 55);
	assert(p8 == 55);

#define test(t,f) \
	do {\
		for (i = 0; i < 500000; i++) { \
			t res1; \
			t res2; \
			t x1; \
			t x2; \
			t f1; \
			t f2; \
			\
			res1 = res2 = random(); \
			x1 = x2 = random(); \
			f1 = f2 = random(); \
			\
			x1 = x1__##f(&res1, f1); \
			x2 = x2__##f(&res2, f2); \
			\
			fprintf(stderr, "%d:  %lld == %lld, %lld == %lld\n", \
			       __LINE__, (long long) x1, \
			       (long long) x2, (long long) res1, \
			       (long long) res2); \
			assert(x1 == x2); \
			assert(res1 == res2); \
		} \
	} while (0)

	test(int64_t, atomic_postadd_int64_t);
	test(int64_t, atomic_add_int64_t);
	test(int64_t, atomic_postsub_int64_t);
	test(int64_t, atomic_sub_int64_t);

	test(uint64_t, atomic_postadd_uint64_t);
	test(uint64_t, atomic_add_uint64_t);
	test(uint64_t, atomic_postsub_uint64_t);
	test(uint64_t, atomic_sub_uint64_t);

	test(uint64_t, atomic_postset_uint64_t_bits);
	test(uint64_t, atomic_set_uint64_t_bits);
	test(uint64_t, atomic_postclear_uint64_t_bits);
	test(uint64_t, atomic_clear_uint64_t_bits);

	test(int32_t, atomic_postadd_int32_t);
	test(int32_t, atomic_add_int32_t);
	test(int32_t, atomic_postsub_int32_t);
	test(int32_t, atomic_sub_int32_t);

	test(uint32_t, atomic_postadd_uint32_t);
	test(uint32_t, atomic_add_uint32_t);
	test(uint32_t, atomic_postsub_uint32_t);
	test(uint32_t, atomic_sub_uint32_t);

	test(uint32_t, atomic_postset_uint32_t_bits);
	test(uint32_t, atomic_set_uint32_t_bits);
	test(uint32_t, atomic_postclear_uint32_t_bits);
	test(uint32_t, atomic_clear_uint32_t_bits);

	test(int16_t, atomic_postadd_int16_t);
	test(int16_t, atomic_add_int16_t);
	test(int16_t, atomic_postsub_int16_t);
	test(int16_t, atomic_sub_int16_t);

	test(uint16_t, atomic_postadd_uint16_t);
	test(uint16_t, atomic_add_uint16_t);
	test(uint16_t, atomic_postsub_uint16_t);
	test(uint16_t, atomic_sub_uint16_t);

	test(uint16_t, atomic_postset_uint16_t_bits);
	test(uint16_t, atomic_set_uint16_t_bits);
	test(uint16_t, atomic_postclear_uint16_t_bits);
	test(uint16_t, atomic_clear_uint16_t_bits);

	test(int8_t, atomic_postadd_int8_t);
	test(int8_t, atomic_add_int8_t);
	test(int8_t, atomic_postsub_int8_t);
	test(int8_t, atomic_sub_int8_t);

	test(uint8_t, atomic_postadd_uint8_t);
	test(uint8_t, atomic_add_uint8_t);
	test(uint8_t, atomic_postsub_uint8_t);
	test(uint8_t, atomic_sub_uint8_t);

	test(uint8_t, atomic_postset_uint8_t_bits);
	test(uint8_t, atomic_set_uint8_t_bits);
	test(uint8_t, atomic_postclear_uint8_t_bits);
	test(uint8_t, atomic_clear_uint8_t_bits);

	return 0;
}
/* Equivalent du _9p_socket_thread( */
void * _9p_rdma_thread( void * Arg )
{
  msk_trans_t   * trans   = Arg  ;

  _9p_rdma_priv * priv    = NULL ;
  _9p_conn_t    * p_9p_conn = NULL ;
  uint8_t       * rdmabuf = NULL ;
  struct ibv_mr * mr      = NULL ;
  msk_data_t    * rdata   = NULL ;
  _9p_datalock_t  * datalock  = NULL ;
  unsigned int i = 0 ;
  int rc = 0 ;

  if( ( priv = gsh_malloc( sizeof(*priv) ) ) == NULL )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc private structure" ) ;
      goto error ;
   }
  memset(priv, 0, sizeof(*priv));
  trans->private_data = priv;

  if( ( p_9p_conn = gsh_malloc( sizeof(*p_9p_conn) ) ) == NULL )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc _9p_conn" ) ;
      goto error ;
   }
  memset(p_9p_conn, 0, sizeof(*p_9p_conn));
  priv->pconn = p_9p_conn;

  for (i = 0; i < FLUSH_BUCKETS; i++)
   {
     pthread_mutex_init(&p_9p_conn->flush_buckets[i].lock, NULL);
     glist_init(&p_9p_conn->flush_buckets[i].list);
   }
  p_9p_conn->sequence = 0 ;
  atomic_store_uint32_t(&p_9p_conn->refcount, 0) ;
  p_9p_conn->trans_type = _9P_RDMA ;
  p_9p_conn->trans_data.rdma_trans = trans ;
  memcpy(&p_9p_conn->addrpeer, msk_get_dst_addr(trans), sizeof(p_9p_conn->addrpeer));

  /* Init the fids pointers array */
  memset( &p_9p_conn->fids, 0, _9P_FID_PER_CONN* sizeof( _9p_fid_t * ) ) ;

  /* Set initial msize. Client may request a lower value during TVERSION */
  p_9p_conn->msize = nfs_param._9p_param._9p_rdma_msize ;

  if( gettimeofday( &p_9p_conn->birth, NULL ) == -1 )
   LogMajor( COMPONENT_9P, "Cannot get connection's time of birth" ) ;

  /* Alloc rdmabuf */
  if( ( rdmabuf = gsh_malloc( (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE)) == NULL )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc rdmabuf" ) ;
      goto error ;
   }
  memset( rdmabuf, 0, (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE);
  priv->rdmabuf = rdmabuf;

  /* Register rdmabuf */
  if( ( mr = msk_reg_mr( trans,
                         rdmabuf,
                         (_9P_RDMA_BUFF_NUM)*_9P_RDMA_CHUNK_SIZE,
                         IBV_ACCESS_LOCAL_WRITE)) == NULL  )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not register rdmabuf" ) ;
      goto error ;
   }

  /* Get prepared to recv data */

  if( ( rdata = gsh_malloc( _9P_RDMA_BUFF_NUM * sizeof(*rdata) ) ) == NULL )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc rdata" ) ;
      goto error ;
   }
  memset( rdata, 0, (_9P_RDMA_BUFF_NUM * sizeof(*rdata)) ) ;
  priv->rdata = rdata;

  if( (datalock = gsh_malloc(_9P_RDMA_BUFF_NUM*sizeof(*datalock))) == NULL )
   {
      LogFatal( COMPONENT_9P, "9P/RDMA: trans handler could not malloc datalock" ) ;
      goto error ;
   }
  memset( datalock, 0, (_9P_RDMA_BUFF_NUM * sizeof(*datalock)) ) ;
  priv->datalock = datalock;

  for( i=0; i < _9P_RDMA_BUFF_NUM; i++)
   {
      rdata[i].data=rdmabuf+i*_9P_RDMA_CHUNK_SIZE ;
      rdata[i].max_size=_9P_RDMA_CHUNK_SIZE ;
      rdata[i].mr = mr;
      datalock[i].data = &rdata[i];
      pthread_mutex_init(&datalock[i].lock, NULL);

      if( i < _9P_RDMA_OUT )
        datalock[i].sender = &datalock[i+_9P_RDMA_OUT] ;
      else
        datalock[i].sender = NULL ;
   } /*  for (unsigned int i=0; i < _9P_RDMA_BUFF_NUM; i++)  */

  for( i=0; i < _9P_RDMA_OUT; i++)
   {
      if( ( rc = msk_post_recv( trans,
                                &rdata[i],
                                _9p_rdma_callback_recv,
				_9p_rdma_callback_recv_err,
                               &(datalock[i]) ) ) != 0 )
       {
          LogEvent( COMPONENT_9P,  "9P/RDMA: trans handler could recv first byte of datalock[%u], rc=%u", i, rc ) ;
          goto error ;
       }
   }

  /* Finalize accept */
  if( ( rc = msk_finalize_accept( trans ) ) != 0 )
   {
      LogMajor( COMPONENT_9P, "9P/RDMA: trans handler could not finalize accept, rc=%u", rc ) ;
      goto error ;
   }

  pthread_exit( NULL ) ;

error:

  _9p_rdma_cleanup_conn_thread( trans ) ;

  pthread_exit( NULL ) ;
} /* _9p_rdma_handle_trans */
예제 #3
0
void *_9p_socket_thread(void *Arg)
{
	long int tcp_sock = (long int)Arg;
	int rc = -1;
	struct pollfd fds[1];
	int fdcount = 1;
	static char my_name[MAXNAMLEN + 1];
	socklen_t addrpeerlen = 0;
	struct sockaddr_storage addrpeer;
	char strcaller[INET6_ADDRSTRLEN];
	request_data_t *req = NULL;
	int tag;
	unsigned long sequence = 0;
	unsigned int i = 0;
	char *_9pmsg = NULL;
	uint32_t msglen;

	struct _9p_conn _9p_conn;

	int readlen = 0;
	int total_readlen = 0;

	snprintf(my_name, MAXNAMLEN, "9p_sock_mgr#fd=%ld", tcp_sock);
	SetNameFunction(my_name);

	/* Init the struct _9p_conn structure */
	memset(&_9p_conn, 0, sizeof(_9p_conn));
	pthread_mutex_init(&_9p_conn.sock_lock, NULL);
	_9p_conn.trans_type = _9P_TCP;
	_9p_conn.trans_data.sockfd = tcp_sock;
	for (i = 0; i < FLUSH_BUCKETS; i++) {
		pthread_mutex_init(&_9p_conn.flush_buckets[i].lock, NULL);
		glist_init(&_9p_conn.flush_buckets[i].list);
	}
	atomic_store_uint32_t(&_9p_conn.refcount, 0);

	/* Init the fids pointers array */
	memset(&_9p_conn.fids, 0, _9P_FID_PER_CONN * sizeof(struct _9p_fid *));

	/* Set initial msize.
	 * Client may request a lower value during TVERSION */
	_9p_conn.msize = _9p_param._9p_tcp_msize;

	if (gettimeofday(&_9p_conn.birth, NULL) == -1)
		LogFatal(COMPONENT_9P, "Cannot get connection's time of birth");

	addrpeerlen = sizeof(addrpeer);
	rc = getpeername(tcp_sock, (struct sockaddr *)&addrpeer,
			 &addrpeerlen);
	if (rc == -1) {
		LogMajor(COMPONENT_9P,
			 "Cannot get peername to tcp socket for 9p, error %d (%s)",
			 errno, strerror(errno));
		/* XXX */
		strncpy(strcaller, "(unresolved)", INET6_ADDRSTRLEN);
		strcaller[12] = '\0';
	} else {
		switch (addrpeer.ss_family) {
		case AF_INET:
			inet_ntop(addrpeer.ss_family,
				  &((struct sockaddr_in *)&addrpeer)->
				  sin_addr, strcaller, INET6_ADDRSTRLEN);
			break;
		case AF_INET6:
			inet_ntop(addrpeer.ss_family,
				  &((struct sockaddr_in6 *)&addrpeer)->
				  sin6_addr, strcaller, INET6_ADDRSTRLEN);
			break;
		default:
			snprintf(strcaller, INET6_ADDRSTRLEN, "BAD ADDRESS");
			break;
		}

		LogEvent(COMPONENT_9P, "9p socket #%ld is connected to %s",
			 tcp_sock, strcaller);
		printf("9p socket #%ld is connected to %s\n", tcp_sock,
		       strcaller);
	}
	_9p_conn.client = get_gsh_client(&addrpeer, false);

	/* Set up the structure used by poll */
	memset((char *)fds, 0, sizeof(struct pollfd));
	fds[0].fd = tcp_sock;
	fds[0].events =
	    POLLIN | POLLPRI | POLLRDBAND | POLLRDNORM | POLLRDHUP | POLLHUP |
	    POLLERR | POLLNVAL;

	for (;;) {
		total_readlen = 0;  /* new message */
		rc = poll(fds, fdcount, -1);
		if (rc == -1) {
			/* timeout = -1 => Wait indefinitely for events */
			/* Interruption if not an issue */
			if (errno == EINTR)
				continue;

			LogCrit(COMPONENT_9P,
				"Got error %u (%s) on fd %ld connect to %s while polling on socket",
				errno, strerror(errno), tcp_sock, strcaller);
		}

		if (fds[0].revents & POLLNVAL) {
			LogEvent(COMPONENT_9P,
				 "Client %s on socket %lu produced POLLNVAL",
				 strcaller, tcp_sock);
			goto end;
		}

		if (fds[0].revents & (POLLERR | POLLHUP | POLLRDHUP)) {
			LogEvent(COMPONENT_9P,
				 "Client %s on socket %lu has shut down and closed",
				 strcaller, tcp_sock);
			goto end;
		}

		if (!(fds[0].revents & (POLLIN | POLLRDNORM)))
			continue;

		/* Prepare to read the message */
		_9pmsg = gsh_malloc(_9p_conn.msize);
		if (_9pmsg == NULL) {
			LogCrit(COMPONENT_9P,
				"Could not allocate 9pmsg buffer for client %s on socket %lu",
				strcaller, tcp_sock);
			goto end;
		}

		/* An incoming 9P request: the msg has a 4 bytes header
		   showing the size of the msg including the header */
		readlen = recv(fds[0].fd, _9pmsg,
			       _9P_HDR_SIZE, MSG_WAITALL);
		if (readlen != _9P_HDR_SIZE)
			goto badmsg;

		msglen = *(uint32_t *) _9pmsg;
		if (msglen > _9p_conn.msize) {
			LogCrit(COMPONENT_9P,
				"Message size too big! got %u, max = %u",
				msglen, _9p_conn.msize);
			goto end;
		}

		LogFullDebug(COMPONENT_9P,
			     "Received 9P/TCP message of size %u from client %s on socket %lu",
			     msglen, strcaller, tcp_sock);

		total_readlen += readlen;
		while (total_readlen < msglen) {
			readlen = recv(fds[0].fd,
				       _9pmsg + total_readlen,
				       msglen - total_readlen,
				       0);

			if (readlen > 0) {
				total_readlen += readlen;
				continue;
			}
			if (readlen == 0 ||
			    (readlen < 0 && errno != EINTR))
				goto badmsg;
		}	/* while */

		server_stats_transport_done(_9p_conn.client,
					    total_readlen, 1, 0,
					    0, 0, 0);

		/* Message is good. */
		req = pool_alloc(request_pool, NULL);

		req->rtype = _9P_REQUEST;
		req->r_u._9p._9pmsg = _9pmsg;
		req->r_u._9p.pconn = &_9p_conn;

		/* Add this request to the request list,
		 * should it be flushed later. */
		tag = *(u16 *) (_9pmsg + _9P_HDR_SIZE +
				_9P_TYPE_SIZE);
		_9p_AddFlushHook(&req->r_u._9p, tag,
				 sequence++);
		LogFullDebug(COMPONENT_9P,
			     "Request tag is %d\n", tag);

		/* Message was OK push it */
		DispatchWork9P(req);

		/* Not our buffer anymore */
		_9pmsg = NULL;
		continue;

badmsg:
		if (readlen == 0)
			LogEvent(COMPONENT_9P,
				 "Premature end for Client %s on socket %lu, total read = %u",
				 strcaller, tcp_sock, total_readlen);
		else if (readlen < 0) {
			LogEvent(COMPONENT_9P,
				 "Read error client %s on socket %lu errno=%d, total read = %u",
				 strcaller, tcp_sock,
				 errno, total_readlen);
		} else
			LogEvent(COMPONENT_9P,
				 "Header too small! for client %s on socket %lu: readlen=%u expected=%u",
				 strcaller, tcp_sock, readlen,
				 _9P_HDR_SIZE);

		/* Either way, we close the connection.
		 * It is not possible to survive
		 * once we get out of sync in the TCP stream
		 * with the client
		 */
		break; /* bail out */
	}			/* for( ;; ) */

end:
	LogEvent(COMPONENT_9P, "Closing connection on socket %lu", tcp_sock);
	close(tcp_sock);

	/* Free buffer if we encountered an error
	 * before we could give it to a worker */
	if (_9pmsg)
		gsh_free(_9pmsg);

	while (atomic_fetch_uint32_t(&_9p_conn.refcount)) {
		LogEvent(COMPONENT_9P, "Waiting for workers to release pconn");
		sleep(1);
	}

	_9p_cleanup_fids(&_9p_conn);

	if (_9p_conn.client != NULL)
		put_gsh_client(_9p_conn.client);

	pthread_exit(NULL);
}				/* _9p_socket_thread */