Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom mutex implementation (half) ignored by unqlite #103

Open
mdorier opened this issue Apr 21, 2020 · 4 comments
Open

Custom mutex implementation (half) ignored by unqlite #103

mdorier opened this issue Apr 21, 2020 · 4 comments
Assignees

Comments

@mdorier
Copy link
Contributor

mdorier commented Apr 21, 2020

I'm on a Unix machine but I would like to have unqlite use a mutex mechanism other than POSIX (I'm using a coroutine library that has its own mutexes). It seems however that unqlite partially ignores my mutex system and keeps using the POSIX one on some (most) occasions.

Here is what I have done to test:

  • I have unqlite compiled with -DUNQLITE_ENABLE_THREADS.
  • unqlite_lib_is_threadsafe() returns 1 when called after opening a database. It returns 0 if called before.
  • I have edited the unqlite code to add a print statement in the UnixMutexNew function. When I run a workload I can see that UnixMutexNew is called.
  • To setup my custom mutex methods, I use unqlite_lib_config(UNQLITE_LIB_CONFIG_USER_MUTEX, &myMutexMethods) before I do anything else with unqlite (I noticed that if I open a database before calling this function, this function will return an error code -4).

My mutex methods also have a print statement to check when they are called. At the moment, when I execute my workload, I see a few instances of my custom mutex being created, however I also see POSIX mutex being created. The creation of the database leads to creating 5 of my custom mutex, and 13 POSIX mutex.

What am I doing wrong that leads to unqlite using both POSIX and my mutexes?

@mdorier
Copy link
Contributor Author

mdorier commented Apr 21, 2020

Some update: I figured out that the jx9 engine inside unqlite was still using POSIX mutexes. To have Unqlite fully rely on my mutex methods, I had to (1) manually copy jx9.h in a location where my code could find it (this file is not installed at the moment), (2) edit the code of unqlite.c to not define JX9_PRIVATE as static; (3) rebuild the unqlite library with this change so jx9_* symbols are visible in the library; (4) use #include "jx9.h", surrounded by the proper extern "C" in my C++ code; and finally (5) call jx9_lib_config(JX9_LIB_CONFIG_USER_MUTEX, &myMutexMethods).

At this point this is mostly a hack. What would be the best path forward to make this cleaner?

@mdorier
Copy link
Contributor Author

mdorier commented Apr 22, 2020

I submitted a PR for what seems to be the most straightforward way to solve the problem: #104

@symisc
Copy link
Owner

symisc commented Apr 23, 2020

Hey Matthieu. In this obscure case, you are planning to use a different paradigm hence coroutines instead of threads and its synchronization mechanism. The cleanest way to do so instead of hacking the internals of the library is to disable threads at all when compiling UnQlite and perform your synchronization operations in your application logic!

@mdorier
Copy link
Contributor Author

mdorier commented Apr 23, 2020

It's a bit more complicated than that; I'm on an HPC machine and using a runtime that mixes threads with coroutines (typically to have 1 thread per core and each thread runs many coroutines that can also migrate from a thread to another). I'm also adding some functions to Jx9 (using unqlite_create_function) and these function do network operations and other things that can context-switch the current coroutine. I need potentially 64 threads to be able to execute Jx9 code on the same database concurrently, and I need to be able to context-switch when doing network operations. I could lock the database with a big mutex when executing a script, and unlock it temporarily in my custom function, but I believe this is a not the most optimal way of enabling concurrent accesses to the DB.

In any case, my PR #104 solves the problem and I have a working code now, which I will clean up by installing the jx9 header from the jx9 distribution instead of having it taken from the unqlite code. All I need now is to be able to enable threading when building unqlite with cmake (see #102).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants