I find the by far most simple solution is using GLX because of its excellent high level interface towards synchronization and double buffering. Please note GLX is not OpenGL, it is an X extension. You need a dummy OpenGL context as SwapBuffers (for some odd reason) demands it but that´s about it.
If you want to do it without GLX for any reason, you may be able to do it by creating double buffers through X Double Buffer Extension (DBE) and syncronize manually towards display using the X Syncronization Extension. You may be able to find something useful calling XSyncListSystemCounters, though it has yet to be confirmed by test:
XSyncListSystemCounters returns a pointer to an array of system counters supported by the display.