aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/float_SUITE_data/fp_drv.c
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /erts/emulator/test/float_SUITE_data/fp_drv.c
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'erts/emulator/test/float_SUITE_data/fp_drv.c')
-rw-r--r--erts/emulator/test/float_SUITE_data/fp_drv.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/erts/emulator/test/float_SUITE_data/fp_drv.c b/erts/emulator/test/float_SUITE_data/fp_drv.c
new file mode 100644
index 0000000000..eb453f6cd6
--- /dev/null
+++ b/erts/emulator/test/float_SUITE_data/fp_drv.c
@@ -0,0 +1,142 @@
+/* ``The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved via the world wide web at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Initial Developer of the Original Code is Ericsson AB. Portions
+ * created by Ericsson are Copyright 2008, Ericsson AB. All Rights
+ * Reserved.''
+ *
+ * $Id$
+ */
+
+#if defined(DEBUG) || 0
+# define PRINTF(X) printf X
+#else
+# define PRINTF(X)
+#endif
+
+#include <math.h>
+#ifdef __WIN32__
+#include <float.h>
+#if defined (__GNUC__)
+int _finite(double x);
+#endif
+#ifndef finite
+#define finite _finite
+#endif
+#endif
+#include "erl_driver.h"
+
+#define ERTS_FP_CONTROL_TEST 0
+#define ERTS_FP_THREAD_TEST 1
+
+static int control(ErlDrvData, unsigned int, char *, int, char **, int);
+
+static ErlDrvEntry fp_drv_entry = {
+ NULL /* init */,
+ NULL /* start */,
+ NULL /* stop */,
+ NULL /* output */,
+ NULL /* ready_input */,
+ NULL /* ready_output */,
+ "fp_drv",
+ NULL /* finish */,
+ NULL /* handle */,
+ control,
+ NULL /* timeout */,
+ NULL /* outputv */,
+ NULL /* ready_async */,
+ NULL /* flush */,
+ NULL /* call */,
+ NULL /* event */,
+ ERL_DRV_EXTENDED_MARKER,
+ ERL_DRV_EXTENDED_MAJOR_VERSION,
+ ERL_DRV_EXTENDED_MINOR_VERSION,
+ ERL_DRV_FLAG_USE_PORT_LOCKING,
+ NULL /* handle2 */,
+ NULL /* process_exit */
+};
+
+DRIVER_INIT(fp_drv)
+{
+ return &fp_drv_entry;
+}
+
+void *
+do_test(void *unused)
+{
+ double x, y, z;
+
+ x = 3.23e133;
+ y = 3.57e257;
+ z = x*y;
+ if (finite(z))
+ return "is finite (1)";
+
+ x = 5.0;
+ y = 0.0;
+ z = x/y;
+ if (finite(z))
+ return "is finite (2)";
+
+ z = log(-1.0);
+ if (finite(z))
+ return "is finite (3)";
+
+ z = log(0.0);
+ if (finite(z))
+ return "is finite (4)";
+
+ return "ok";
+}
+
+static int control(ErlDrvData drv_data,
+ unsigned int command,
+ char *buf, int len,
+ char **rbuf, int rlen)
+{
+ char *res_str;
+ PRINTF(("control(%p, %d, ...) called\r\n", drv_data, command));
+
+ switch (command) {
+ case ERTS_FP_THREAD_TEST: {
+ ErlDrvTid tid;
+ ErlDrvSysInfo info;
+ driver_system_info(&info, sizeof(ErlDrvSysInfo));
+ if (!info.thread_support)
+ res_str = "skip: no thread support";
+ else if (0 != erl_drv_thread_create("test", &tid, do_test, NULL, NULL))
+ res_str = "failed to create thread";
+ else if (0 != erl_drv_thread_join(tid, &res_str))
+ res_str = "failed to join thread";
+ break;
+ }
+ case ERTS_FP_CONTROL_TEST:
+ res_str = do_test(NULL);
+ break;
+ default:
+ res_str = "unknown command";
+ break;
+ }
+
+ done: {
+ int res_len = strlen(res_str);
+ if (res_len > rlen) {
+ char *abuf = driver_alloc(sizeof(char)*res_len);
+ if (!abuf)
+ return 0;
+ *rbuf = abuf;
+ }
+
+ memcpy((void *) *rbuf, (void *) res_str, res_len);
+
+ return res_len;
+ }
+}