Squashed 'third_party/osqp/' content from commit 33454b3e23

Change-Id: I056df0582ca06664e86554c341a94c47ab932001
git-subtree-dir: third_party/osqp
git-subtree-split: 33454b3e236f1f44193bfbbb6b8c8e71f8f04e9a
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/lin_sys/direct/pardiso/pardiso_loader.c b/lin_sys/direct/pardiso/pardiso_loader.c
new file mode 100644
index 0000000..f120e47
--- /dev/null
+++ b/lin_sys/direct/pardiso/pardiso_loader.c
@@ -0,0 +1,102 @@
+#include "lib_handler.h"
+#include "pardiso_loader.h"
+
+#include "glob_opts.h"
+#include "constants.h"
+
+#ifdef IS_WINDOWS
+#define PARDISOLIBNAME "mkl_rt." SHAREDLIBEXT
+#else
+#define PARDISOLIBNAME "libmkl_rt." SHAREDLIBEXT
+#endif
+
+typedef void (*voidfun)(void);
+
+voidfun lh_load_sym (soHandle_t h, const char *symName);
+
+
+// Interfaces for Pardiso functions
+typedef void (*pardiso_t)(void**, const c_int*, const c_int*, const c_int*,
+                          const c_int*, const c_int*, const c_float*,
+                          const c_int*, const c_int*, c_int*,
+                          const c_int*, c_int*, const c_int*, c_float*,
+                          c_float*, c_int*);
+typedef int (*mkl_set_ifl_t)(int);
+typedef int (*mkl_get_mt_t)();
+
+
+// Handlers are static variables
+static soHandle_t Pardiso_handle = OSQP_NULL;
+static pardiso_t func_pardiso = OSQP_NULL;
+static mkl_set_ifl_t func_mkl_set_interface_layer = OSQP_NULL;
+static mkl_get_mt_t func_mkl_get_max_threads = OSQP_NULL;
+
+// Wrappers for loaded Pardiso function handlers
+void pardiso(void** pt, const c_int* maxfct, const c_int* mnum,
+                  const c_int* mtype, const c_int* phase, const c_int* n,
+                  const c_float* a, const c_int* ia, const c_int* ja,
+                  c_int* perm, const c_int* nrhs, c_int* iparm,
+                  const c_int* msglvl, c_float* b, c_float* x,
+                  c_int* error) {
+	if(func_pardiso){
+            // Call function pardiso only if it has been initialized
+	    func_pardiso(pt, maxfct, mnum, mtype, phase, n, a, ia, ja,
+			 perm, nrhs, iparm, msglvl, b, x, error);
+	}
+	else
+	{
+#ifdef PRINTING
+		c_eprint("Pardiso not loaded correctly");
+#endif
+	}
+}
+
+c_int mkl_set_interface_layer(c_int code) {
+    return (c_int)func_mkl_set_interface_layer((int)code);
+}
+
+c_int mkl_get_max_threads() {
+    return (c_int)func_mkl_get_max_threads();
+}
+
+
+c_int lh_load_pardiso(const char* libname) {
+    // DEBUG
+    // if (Pardiso_handle) return 0;
+
+    // Load Pardiso library
+    if (libname) {
+        Pardiso_handle = lh_load_lib(libname);
+    } else { /* try a default library name */
+        Pardiso_handle = lh_load_lib(PARDISOLIBNAME);
+    }
+    if (!Pardiso_handle) return 1;
+
+    // Load Pardiso functions
+    func_pardiso = (pardiso_t)lh_load_sym(Pardiso_handle, "pardiso");
+    if (!func_pardiso) return 1;
+
+    func_mkl_set_interface_layer = (mkl_set_ifl_t)lh_load_sym(Pardiso_handle,
+                                                    "MKL_Set_Interface_Layer");
+    if (!func_mkl_set_interface_layer) return 1;
+
+    func_mkl_get_max_threads = (mkl_get_mt_t)lh_load_sym(Pardiso_handle,
+                                                    "MKL_Get_Max_Threads");
+    if (!func_mkl_get_max_threads) return 1;
+
+    return 0;
+}
+
+c_int lh_unload_pardiso() {
+
+    if (Pardiso_handle == OSQP_NULL) return 0;
+
+    return lh_unload_lib(Pardiso_handle);
+
+    /* If multiple OSQP objects are laoded, the lines below cause a crash */
+    // Pardiso_handle = OSQP_NULL;
+    // func_pardiso = OSQP_NULL;
+    // func_mkl_set_interface_layer = OSQP_NULL;
+    // func_mkl_get_max_threads = OSQP_NULL;
+
+}