Note: Debug Sync Points were based on user-level locks. They were part of the MySQL code until the 6.0.5 and 5.1.46 versions. Debug Sync Points have been removed from the code in favor of the Debug Sync Facility.
Debug Sync Points give user-level locks the ability to synchronize at arbitrary points in code.
open_tables(...) DBUG_SYNC_POINT("debug_lock.after_open_tables", 10); lock_tables(...)
The synchronization points behave similar to
RELEASE_LOCK(<whatever the thread has>); IS_FREE_LOCK(str) OR (GET_LOCK(str,timeout) AND RELEASE_LOCK(str))
This means that the synchronization point releases any lock that the thread may have, waits to acquire the lock if another thread has it, and releases it immediately. If the lock is free (not used by any thread), the synchronization point does nothing but release any user-level lock of the current thread.
So the idea of DBUG_SYNC_POINT is that it does nothing when the user-level lock is not in use by any thread, and does wait for it to become free when it is in use. That way you can block a thread at a synchronization point by acquiring the user-level lock and let it continue by releasing the lock.
This can be used as a "signal". The thread acquires a lock (the "signal" lock) and releases it implicitly when reaching the synchronization point. The other thread, which tried to get the "signal" lock after this thread, gets the lock at the same moment and can continue.
It can be used as a "wait". The other thread has the "synchronization point" lock ("debug_lock.after_open_tables" in this example) and this thread blocks on it in the synchronization point.
Unfortunately I was not able to figure out, how to use it for "signal" _plus_ "wait". While the other thread could have the "synchronization point" lock and this thread have the "signal" lock, and hence reaching the synchronization point would release the "signal" lock and wait on the "synchronization point" lock, the other thread would not be able to wait on the "signal" lock, because it has the "synchronization point" lock. A thread can have one user lock only. When the other thread tries to wait for the "signal" lock, it implicitly releases the "synchronization point" lock. This would be okay if one could be sure that this thread reached the synchronization point before the other thread releases the "synchronization point" lock. Otherwise no wait would happen at the synchronization point. The test would not test what it should test.
A possible workaround might be a third thread, which takes the "synchronization point" lock in the beginning and releases it at the right moment. But this could easily lead to a big number of threads for more complex situations. Tests using this method are likely to become ununderstandable.
It is probably a bug in the implementation that DBUG_SYNC_POINT releases any lock unconditionally. The method is not widely used. I found just one single use in sql_repl.cc. I guess lock releasing was added to prevent that a synchronization point could wait on the threads own lock. The behavior could be fixed easily if the method should find more use.
The DBUG_SYNC_POINT method is available in debug servers only. If it is used in the test suite, similar precautions for writing tests have to be taken as mentioned in the "Dbug Sleep" section.
Note: Backup Breakpoints were based on DBUG_SYNC_POINT. They were part of the MySQL code in some early 6.0 versions. Backup Breakpoints have been removed from the code in favor of the Debug Sync Facility.
open_tables(...) BACKUP_BREAKPOINT("bp_after_open_tables"); lock_tables(...)
The BACKUP_BREAKPOINT macro consists basically of:
DBUG_EXECUTE_IF("backup_debug", DBUG_SYNC_POINT((S), 300))
Opportunities and downsides of the DBUG_SYNC_POINT method apply here too.
In addition we had the downside that DBUG tracing was hampered as explained in the "Dbug Sleep" section.