summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2019-06-14 18:01:21 +0200
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2019-06-14 18:34:12 +0200
commitdc0d7aad38f21629074416c2b2e8a5cf9c269785 (patch)
tree4f14a9643843baf1cf453ae91fabc9bd7f903266
parent5d0b8b4ac73d434160c1b71a7922ad7309082a46 (diff)
downloadmicrocom-dc0d7aad38f21629074416c2b2e8a5cf9c269785.tar.gz
microcom-dc0d7aad38f21629074416c2b2e8a5cf9c269785.tar.xz
can: Get rid of pthread for can transfers
Since there are ios specific read and write callbacks the needed overhead for can transfers can be implemented in these which makes the separate thread superfluous. This simplifies the can driver considerably. As a consequence microcom doesn't need pthreads any more and the respective changes in configure.ac can go away, too. The configuration for lgtm which assert that the AX_PTHREAD macro is available can be dropped and the travis configuration can be simplified accordingly. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Closes: https://github.com/pengutronix/microcom/issues/8
-rw-r--r--.travis.yml4
-rw-r--r--can.c137
-rw-r--r--configure.ac6
-rw-r--r--lgtm.yml5
4 files changed, 47 insertions, 105 deletions
diff --git a/.travis.yml b/.travis.yml
index 87116f4..0723a3a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,10 +1,6 @@
language: c
compiler: gcc
dist: trusty
-addons:
- apt:
- packages:
- - autoconf-archive
script:
- autoreconf -fi
- ./configure
diff --git a/can.c b/can.c
index 38e8e96..e64127b 100644
--- a/can.c
+++ b/can.c
@@ -15,7 +15,6 @@
*
*/
-#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
@@ -34,29 +33,59 @@
#include "microcom.h"
-enum socket_local_enum {
- SOCKET_CANSIDE,
- SOCKET_TERMSIDE,
- SOCKET_MAX,
-};
-
struct can_data {
- int socket_can;
- int socket_local[SOCKET_MAX];
int can_id;
};
static struct can_data data;
-static pthread_t can_thread;
static ssize_t can_write(struct ios_ops *ios, const void *buf, size_t count)
{
- return write(ios->fd, buf, count);
+ size_t loopcount;
+ ssize_t ret = 0, err;
+
+ struct can_frame to_can = {
+ .can_id = data.can_id,
+ };
+
+ while (count > 0) {
+ loopcount = min(count, sizeof(to_can.data));
+ memcpy(to_can.data, buf, loopcount);
+ to_can.can_dlc = loopcount;
+retry:
+ err = write(ios->fd, &to_can, sizeof(to_can));
+ if (err < 0 && errno == EINTR)
+ goto retry;
+
+ if (err < 0)
+ return err;
+
+ assert(err < count);
+ buf += err;
+ count -= err;
+ ret += err;
+ }
+
+ return ret;
}
static ssize_t can_read(struct ios_ops *ios, void *buf, size_t count)
{
- return read(ios->fd, buf, count);
+ struct can_frame from_can;
+ ssize_t ret;
+
+retry:
+ ret = read(ios->fd, &from_can, sizeof(from_can));
+ if (ret < 0 && errno != EINTR)
+ goto retry;
+
+ if (ret < 0)
+ return ret;
+
+ assert(count >= from_can.can_dlc);
+ memcpy(buf, from_can.data, from_can.can_dlc);
+
+ return from_can.can_dlc;
}
static int can_set_speed(struct ios_ops *ios, unsigned long speed)
@@ -76,75 +105,10 @@ static int can_send_break(struct ios_ops *ios)
static void can_exit(struct ios_ops *ios)
{
- shutdown(ios->fd, SHUT_RDWR);
close(ios->fd);
- pthread_join(can_thread, NULL);
free(ios);
}
-static void *can_thread_fun(void *_data)
-{
- struct can_data *data = _data;
- struct can_frame to_can = {
- .can_id = data->can_id,
- };
- struct can_frame from_can;
- fd_set ready;
- int ret, fd_max;
-
- fd_max = max(data->socket_can, data->socket_local[SOCKET_CANSIDE]);
- fd_max++;
-
- while (1) {
- FD_ZERO(&ready);
- FD_SET(data->socket_can, &ready);
- FD_SET(data->socket_local[SOCKET_CANSIDE], &ready);
-
- ret = select(fd_max, &ready, NULL, NULL, NULL);
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- goto exit;
- }
-
- /* CAN -> TERMINAL */
- if (FD_ISSET(data->socket_can, &ready)) {
- ret = read(data->socket_can, &from_can, sizeof(from_can));
- if ((ret == -1 && errno != EINTR) ||
- ret != sizeof(from_can))
- goto exit;
-
- ret = write(data->socket_local[SOCKET_CANSIDE],
- from_can.data, from_can.can_dlc);
- if ((ret == -1 && errno != EINTR) ||
- ret != from_can.can_dlc)
- goto exit;
- }
-
- /* TERMINAL -> CAN */
- if (FD_ISSET(data->socket_local[SOCKET_CANSIDE], &ready)) {
- ret = read(data->socket_local[SOCKET_CANSIDE],
- to_can.data, sizeof(to_can.data));
- if ((ret == -1 && errno != EINTR) ||
- ret == 0)
- goto exit;
-
- to_can.can_dlc = ret;
- ret = write(data->socket_can, &to_can, sizeof(to_can));
- if ((ret == -1 && errno != EINTR) ||
- ret != sizeof(to_can))
- goto exit;
- }
- }
-
- exit:
- shutdown(data->socket_local[SOCKET_CANSIDE], SHUT_RDWR);
- close(data->socket_local[SOCKET_CANSIDE]);
- close(data->socket_can);
-
- return NULL;
-}
-
struct ios_ops *can_init(char *interface_id)
{
struct ios_ops *ios;
@@ -201,39 +165,30 @@ struct ios_ops *can_init(char *interface_id)
/* no cleanups on failure, we exit anyway */
- data.socket_can = socket(PF_CAN, SOCK_RAW, CAN_RAW);
- if (data.socket_can < 0) {
+ ios->fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+ if (ios->fd < 0) {
perror("socket");
return NULL;
}
- if (setsockopt(data.socket_can, SOL_CAN_RAW, CAN_RAW_FILTER,
+ if (setsockopt(ios->fd, SOL_CAN_RAW, CAN_RAW_FILTER,
filter, sizeof(filter))) {
perror("setsockopt");
return NULL;
}
strcpy(ifr.ifr_name, interface);
- if (ioctl(data.socket_can, SIOCGIFINDEX, &ifr)) {
+ if (ioctl(ios->fd, SIOCGIFINDEX, &ifr)) {
printf("%s: %s\n", interface, strerror(errno));
return NULL;
}
addr.can_ifindex = ifr.ifr_ifindex;
- if (bind(data.socket_can, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ if (bind(ios->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return NULL;
}
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, data.socket_local) < 0) {
- perror("socketpair");
- return NULL;
- }
-
- if (pthread_create(&can_thread, NULL, can_thread_fun, &data) != 0)
- return NULL;
-
- ios->fd = data.socket_local[SOCKET_TERMSIDE];
printf("connected to %s (rx_id=%x, tx_id=%x)\n",
interface, filter->can_id, data.can_id);
diff --git a/configure.ac b/configure.ac
index 18b4346..d1a90b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,6 @@ AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
-AX_PTHREAD
AC_SYS_LARGEFILE
# Checks for libraries.
@@ -38,10 +37,7 @@ AS_IF([test "x$enable_can" != "xno"],
])
AS_IF([test "x$enable_can" = "xyes"],
- [AC_DEFINE([USE_CAN], [1], [Define if can mode should be built-in])
- LIBS="$PTHREAD_LIBS $LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- CC="$PTHREAD_CC"])
+ [AC_DEFINE([USE_CAN], [1], [Define if can mode should be built-in])])
AM_CONDITIONAL([CAN], [test "x$enable_can" = "xyes"])
diff --git a/lgtm.yml b/lgtm.yml
deleted file mode 100644
index 3c21140..0000000
--- a/lgtm.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-extraction:
- cpp:
- prepare:
- packages:
- - autoconf-archive