mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-04 23:42:40 +08:00

modified: Makefile modified: all_test.go modified: internal/bin/bin_linux_386.go modified: internal/bin/bin_linux_amd64.go modified: internal/mptest/mptest_linux_386.go modified: internal/mptest/mptest_linux_amd64.go modified: internal/threadtest4/threadtest4_linux_386.go modified: internal/threadtest4/threadtest4_linux_amd64.go
597 lines
22 KiB
Go
597 lines
22 KiB
Go
// Code generated by ccgo. DO NOT EDIT.
|
|
|
|
// threadtest4.c
|
|
|
|
// 2014-12-11
|
|
//
|
|
// The author disclaims copyright to this source code. In place of
|
|
// a legal notice, here is a blessing:
|
|
//
|
|
// May you do good and not evil.
|
|
// May you find forgiveness for yourself and forgive others.
|
|
// May you share freely, never taking more than you give.
|
|
//
|
|
// *************************************************************************
|
|
// This file implements a simple standalone program used to stress the
|
|
// SQLite library when accessing the same set of databases simultaneously
|
|
// from multiple threads in shared-cache mode.
|
|
//
|
|
// This test program runs on unix-like systems only. It uses pthreads.
|
|
// To compile:
|
|
//
|
|
// gcc -g -Wall -I. threadtest4.c sqlite3.c -ldl -lpthread
|
|
//
|
|
// To run:
|
|
//
|
|
// ./a.out 10
|
|
//
|
|
// The argument is the number of threads. There are also options, such
|
|
// as -wal and -multithread and -serialized.
|
|
//
|
|
// Consider also compiling with clang instead of gcc and adding the
|
|
// -fsanitize=thread option.
|
|
|
|
package main
|
|
|
|
import (
|
|
"math"
|
|
"os"
|
|
"unsafe"
|
|
|
|
"github.com/cznic/crt"
|
|
"github.com/cznic/sqlite/internal/bin"
|
|
)
|
|
|
|
var argv []*int8
|
|
|
|
func main() {
|
|
for _, v := range os.Args {
|
|
argv = append(argv, (*int8)(crt.CString(v)))
|
|
}
|
|
argv = append(argv, nil)
|
|
X_start(crt.NewTLS(), int32(len(os.Args)), &argv[0])
|
|
}
|
|
|
|
func X_start(tls *crt.TLS, _argc int32, _argv **int8) {
|
|
crt.X__register_stdfiles(tls, Xstdin, Xstdout, Xstderr)
|
|
crt.X__builtin_exit(tls, Xmain(tls, _argc, _argv))
|
|
}
|
|
|
|
var Xstdin unsafe.Pointer
|
|
|
|
func init() {
|
|
Xstdin = unsafe.Pointer(&X__stdfiles)
|
|
}
|
|
|
|
var X__stdfiles [3]unsafe.Pointer
|
|
|
|
var Xstdout unsafe.Pointer
|
|
|
|
func init() {
|
|
Xstdout = (unsafe.Pointer)(uintptr(unsafe.Pointer(&X__stdfiles)) + 4)
|
|
}
|
|
|
|
var Xstderr unsafe.Pointer
|
|
|
|
func init() {
|
|
Xstderr = (unsafe.Pointer)(uintptr(unsafe.Pointer(&X__stdfiles)) + 8)
|
|
}
|
|
|
|
func Xmain(tls *crt.TLS, _argc int32, _argv **int8) (r0 int32) {
|
|
var _nWorker, _i, _nErr, _nTest, _rc int32
|
|
var _wkrFlags uint32
|
|
var _1_z *int8
|
|
var _db unsafe.Pointer
|
|
var _wrMutex crt.Xpthread_mutex_t
|
|
var _infoTop XWorkerInfo
|
|
var _aInfo, _p *XWorkerInfo
|
|
r0 = i32(0)
|
|
_nWorker = i32(0)
|
|
_wkrFlags = u32(0)
|
|
_nErr = i32(0)
|
|
_nTest = i32(0)
|
|
_db = nil
|
|
bin.Xsqlite3_config(tls, i32(2))
|
|
_i = i32(1)
|
|
_0:
|
|
if _i >= _argc {
|
|
goto _3
|
|
}
|
|
_1_z = *(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 4*uintptr(_i)))
|
|
if int32(*(*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_1_z)) + 1*uintptr(i32(0))))) != i32(45) {
|
|
goto _4
|
|
}
|
|
if (int32(*(*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_1_z)) + 1*uintptr(i32(1))))) == i32(45)) && (int32(*(*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_1_z)) + 1*uintptr(i32(2))))) != i32(0)) {
|
|
*(*uintptr)(unsafe.Pointer(&_1_z)) += uintptr(1)
|
|
}
|
|
if crt.Xstrcmp(tls, _1_z, str(0)) == i32(0) {
|
|
bin.Xsqlite3_config(tls, i32(2))
|
|
{
|
|
p := &_wkrFlags
|
|
*p = (*p) & uint32(i32(-2))
|
|
sink0(*p)
|
|
}
|
|
goto _14
|
|
}
|
|
if crt.Xstrcmp(tls, _1_z, str(13)) == i32(0) {
|
|
bin.Xsqlite3_config(tls, i32(3))
|
|
{
|
|
p := &_wkrFlags
|
|
*p = (*p) | uint32(i32(1))
|
|
sink0(*p)
|
|
}
|
|
goto _14
|
|
}
|
|
if crt.Xstrcmp(tls, _1_z, str(25)) == i32(0) {
|
|
{
|
|
p := &_wkrFlags
|
|
*p = (*p) | uint32(i32(2))
|
|
sink0(*p)
|
|
}
|
|
goto _14
|
|
}
|
|
if crt.Xstrcmp(tls, _1_z, str(30)) == i32(0) {
|
|
{
|
|
p := &_wkrFlags
|
|
*p = (*p) | uint32(i32(4))
|
|
sink0(*p)
|
|
}
|
|
goto _14
|
|
}
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(37), unsafe.Pointer(*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 4*uintptr(_i)))))
|
|
crt.Xexit(tls, i32(1))
|
|
_14:
|
|
goto _20
|
|
_4:
|
|
if int32(*(*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_1_z)) + 1*uintptr(i32(0))))) < i32(49) || int32(*(*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_1_z)) + 1*uintptr(i32(0))))) > i32(57) || _nWorker != i32(0) {
|
|
goto _18
|
|
}
|
|
_nWorker = crt.Xatoi(tls, _1_z)
|
|
if _nWorker < i32(2) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(70))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
goto _20
|
|
_18:
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(92), unsafe.Pointer(*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 4*uintptr(_i)))))
|
|
crt.Xexit(tls, i32(1))
|
|
_20:
|
|
_i += 1
|
|
goto _0
|
|
_3:
|
|
if _nWorker == i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(127), unsafe.Pointer(*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 4*uintptr(i32(0))))))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
if bin.Xsqlite3_threadsafe(tls) == 0 {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(260))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_initialize(tls)
|
|
bin.Xsqlite3_enable_shared_cache(tls, i32(1))
|
|
crt.Xpthread_mutex_init(tls, &_wrMutex, nil)
|
|
crt.Xunlink(tls, str(299))
|
|
crt.Xunlink(tls, str(312))
|
|
crt.Xunlink(tls, str(325))
|
|
_rc = bin.Xsqlite3_open(tls, str(299), (**bin.Xsqlite3)(unsafe.Pointer(&_db)))
|
|
if _rc != i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(338))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
crt.Xmemset(tls, (unsafe.Pointer)(&_infoTop), i32(0), u32(40))
|
|
*(*unsafe.Pointer)(unsafe.Pointer(&(_infoTop.X4))) = _db
|
|
*(*uint32)(unsafe.Pointer(&(_infoTop.X2))) = _wkrFlags
|
|
_p = &_infoTop
|
|
if (_wkrFlags & uint32(i32(2))) != 0 {
|
|
_run_sql(tls, _p, str(382))
|
|
}
|
|
_run_sql(tls, _p, str(406))
|
|
_run_sql(tls, _p, str(429))
|
|
_run_sql(tls, _p, str(485))
|
|
_run_sql(tls, _p, str(515))
|
|
_run_sql(tls, _p, str(544))
|
|
_run_sql(tls, _p, str(577))
|
|
_run_sql(tls, _p, str(639))
|
|
_run_sql(tls, _p, str(675))
|
|
_run_sql(tls, _p, str(710))
|
|
_run_sql(tls, _p, str(743))
|
|
_run_sql(tls, _p, str(805))
|
|
_run_sql(tls, _p, str(841))
|
|
_aInfo = (*XWorkerInfo)(_safe_malloc(tls, int32(u32(40)*uint32(_nWorker))))
|
|
crt.Xmemset(tls, (unsafe.Pointer)(_aInfo), i32(0), u32(40)*uint32(_nWorker))
|
|
_i = i32(0)
|
|
_25:
|
|
if _i >= _nWorker {
|
|
goto _28
|
|
}
|
|
*(*int32)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X0))) = _i + i32(1)
|
|
*(*int32)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X1))) = _nWorker
|
|
*(*uint32)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X2))) = _wkrFlags
|
|
*(*unsafe.Pointer)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X3))) = _db
|
|
*(**crt.Xpthread_mutex_t)(unsafe.Pointer((*unsafe.Pointer)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X9))))) = &_wrMutex
|
|
_rc = crt.Xpthread_create(tls, (*uint32)(unsafe.Pointer(&((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X8))), nil, _worker_thread, (unsafe.Pointer)((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i)))))
|
|
if _rc != i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(876), _i+i32(1))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
crt.Xsched_yield(tls)
|
|
_i += 1
|
|
goto _25
|
|
_28:
|
|
_i = i32(0)
|
|
_30:
|
|
if _i >= _nWorker {
|
|
goto _33
|
|
}
|
|
crt.Xpthread_join(tls, (*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i))).X8, nil)
|
|
crt.Xprintf(tls, str(914), (*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i))).X0, (*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i))).X5, (*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i))).X6)
|
|
if ((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X7) != nil {
|
|
crt.Xprintf(tls, str(954), unsafe.Pointer((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo))+40*uintptr(_i))).X7))
|
|
goto _35
|
|
}
|
|
crt.Xprintf(tls, str(960))
|
|
_35:
|
|
{
|
|
p := &_nErr
|
|
*p = (*p) + ((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X5)
|
|
sink1(*p)
|
|
}
|
|
{
|
|
p := &_nTest
|
|
*p = (*p) + ((*XWorkerInfo)(unsafe.Pointer(uintptr((unsafe.Pointer)(_aInfo)) + 40*uintptr(_i))).X6)
|
|
sink1(*p)
|
|
}
|
|
crt.Xfflush(tls, (*crt.XFILE)(Xstdout))
|
|
_i += 1
|
|
goto _30
|
|
_33:
|
|
bin.Xsqlite3_close(tls, (*bin.Xsqlite3)(_db))
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_aInfo))
|
|
crt.Xprintf(tls, str(962), _nErr, _nTest)
|
|
return _nErr
|
|
|
|
_ = _wrMutex
|
|
_ = _infoTop
|
|
panic(0)
|
|
}
|
|
|
|
// Run a SQL statements. Panic if unable.
|
|
func _run_sql(tls *crt.TLS, _p *XWorkerInfo, _zFormat *int8, args ...interface{}) {
|
|
var _rc, _nRetry int32
|
|
var _zSql *int8
|
|
var _pStmt unsafe.Pointer
|
|
var _ap []interface{}
|
|
_pStmt = nil
|
|
_nRetry = i32(0)
|
|
_ap = args
|
|
_zSql = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_ap = nil
|
|
_check_oom(tls, (unsafe.Pointer)(_zSql))
|
|
_rc = bin.Xsqlite3_prepare_v2(tls, (*bin.Xsqlite3)(_p.X4), _zSql, i32(-1), &_pStmt, nil)
|
|
if _rc != i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(991), _rc, bin.Xsqlite3_extended_errcode(tls, (*bin.Xsqlite3)(_p.X4)), unsafe.Pointer(bin.Xsqlite3_errmsg(tls, (*bin.Xsqlite3)(_p.X4))), unsafe.Pointer(_zSql))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
_worker_trace(tls, _p, str(1036), unsafe.Pointer(_zSql))
|
|
_1:
|
|
if store1(&_rc, bin.Xsqlite3_step(tls, _pStmt)) == i32(101) {
|
|
goto _2
|
|
}
|
|
if (_rc&i32(255)) != i32(5) && (_rc&i32(255)) != i32(6) {
|
|
goto _4
|
|
}
|
|
bin.Xsqlite3_reset(tls, _pStmt)
|
|
_nRetry += 1
|
|
if _nRetry < i32(10) {
|
|
_worker_trace(tls, _p, str(1049), _nRetry, unsafe.Pointer(_zSql))
|
|
crt.Xsched_yield(tls)
|
|
goto _1
|
|
}
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(1067), _p.X0, unsafe.Pointer(_zSql))
|
|
crt.Xexit(tls, i32(1))
|
|
_4:
|
|
if _rc != i32(100) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(1109), _rc, bin.Xsqlite3_extended_errcode(tls, (*bin.Xsqlite3)(_p.X4)), unsafe.Pointer(bin.Xsqlite3_errmsg(tls, (*bin.Xsqlite3)(_p.X4))), unsafe.Pointer(_zSql))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
goto _1
|
|
_2:
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zSql))
|
|
bin.Xsqlite3_finalize(tls, _pStmt)
|
|
}
|
|
|
|
// Report an OOM error and die if the argument is NULL
|
|
func _check_oom(tls *crt.TLS, _x unsafe.Pointer) {
|
|
if _x == nil {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(1151))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
}
|
|
|
|
// Print a trace message for a worker
|
|
func _worker_trace(tls *crt.TLS, _p *XWorkerInfo, _zFormat *int8, args ...interface{}) {
|
|
var _zMsg *int8
|
|
var _ap []interface{}
|
|
if ((_p.X2) & uint32(i32(4))) == uint32(i32(0)) {
|
|
return
|
|
}
|
|
_ap = args
|
|
_zMsg = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_check_oom(tls, (unsafe.Pointer)(_zMsg))
|
|
_ap = nil
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(1166), _p.X0, unsafe.Pointer(_zMsg))
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zMsg))
|
|
}
|
|
|
|
// Allocate memory. If the allocation fails, print an error message and
|
|
// kill the process.
|
|
func _safe_malloc(tls *crt.TLS, _sz int32) (r0 unsafe.Pointer) {
|
|
var _x unsafe.Pointer
|
|
_x = bin.Xsqlite3_malloc(tls, func() int32 {
|
|
if _sz > i32(0) {
|
|
return _sz
|
|
}
|
|
return i32(1)
|
|
}())
|
|
_check_oom(tls, _x)
|
|
return _x
|
|
}
|
|
|
|
// Each thread runs the following function.
|
|
func _worker_thread(tls *crt.TLS, _pArg unsafe.Pointer) (r0 unsafe.Pointer) {
|
|
var _iOuter, _i, _rc int32
|
|
var _pStmt unsafe.Pointer
|
|
var _p *XWorkerInfo
|
|
_p = (*XWorkerInfo)(_pArg)
|
|
crt.Xprintf(tls, str(1183), _p.X0)
|
|
crt.Xfflush(tls, (*crt.XFILE)(Xstdout))
|
|
_iOuter = i32(1)
|
|
_0:
|
|
if _iOuter > (_p.X1) {
|
|
goto _3
|
|
}
|
|
_worker_open_connection(tls, _p, _iOuter)
|
|
_i = i32(0)
|
|
_4:
|
|
if _i >= i32(4) {
|
|
goto _7
|
|
}
|
|
_worker_add_content(tls, _p, (_i*i32(100))+i32(1), (_i+i32(1))*i32(100), (((_p.X0)+_iOuter)%i32(3))+i32(1))
|
|
_worker_add_content(tls, _p, (_i*i32(100))+i32(1), (_i+i32(1))*i32(100), ((((_p.X0)+_iOuter)+i32(1))%i32(3))+i32(1))
|
|
_worker_add_content(tls, _p, (_i*i32(100))+i32(1), (_i+i32(1))*i32(100), ((((_p.X0)+_iOuter)+i32(2))%i32(3))+i32(1))
|
|
_i += 1
|
|
goto _4
|
|
_7:
|
|
_pStmt = _prep_sql(tls, _p.X4, str(1202), _p.X0)
|
|
_worker_trace(tls, _p, str(1239), unsafe.Pointer(bin.Xsqlite3_sql(tls, _pStmt)))
|
|
_rc = bin.Xsqlite3_step(tls, _pStmt)
|
|
if _rc != i32(100) {
|
|
_worker_error(tls, _p, str(1250), unsafe.Pointer(bin.Xsqlite3_sql(tls, _pStmt)))
|
|
goto _10
|
|
}
|
|
if bin.Xsqlite3_column_int(tls, _pStmt, i32(0)) != i32(400) {
|
|
_worker_error(tls, _p, str(1269), bin.Xsqlite3_column_int(tls, _pStmt, i32(0)))
|
|
}
|
|
_10:
|
|
bin.Xsqlite3_finalize(tls, _pStmt)
|
|
if (_p.X5) != 0 {
|
|
goto _3
|
|
}
|
|
if ((_iOuter + (_p.X0)) % i32(3)) == i32(0) {
|
|
bin.Xsqlite3_db_release_memory(tls, (*bin.Xsqlite3)(_p.X4))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
}
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1286))
|
|
_run_sql(tls, _p, str(1293))
|
|
_run_sql(tls, _p, str(1325))
|
|
_run_sql(tls, _p, str(1357))
|
|
_run_sql(tls, _p, str(1389))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
if _iOuter == (_p.X0) {
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1399))
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
}
|
|
_pStmt = _prep_sql(tls, _p.X4, str(1406), _p.X0, _p.X0, _p.X0)
|
|
_worker_trace(tls, _p, str(1239), unsafe.Pointer(bin.Xsqlite3_sql(tls, _pStmt)))
|
|
_i = i32(0)
|
|
_14:
|
|
if _i >= (_p.X1) {
|
|
goto _17
|
|
}
|
|
_rc = bin.Xsqlite3_step(tls, _pStmt)
|
|
if _rc != i32(100) {
|
|
_worker_error(tls, _p, str(1250), unsafe.Pointer(bin.Xsqlite3_sql(tls, _pStmt)))
|
|
goto _17
|
|
}
|
|
crt.Xsched_yield(tls)
|
|
_i += 1
|
|
goto _14
|
|
_17:
|
|
bin.Xsqlite3_finalize(tls, _pStmt)
|
|
if (_p.X5) != 0 {
|
|
goto _3
|
|
}
|
|
_worker_delete_all_content(tls, _p, ((_p.X0)+_iOuter)%i32(2))
|
|
_worker_close_connection(tls, _p)
|
|
*(*unsafe.Pointer)(unsafe.Pointer(&(_p.X4))) = nil
|
|
_iOuter += 1
|
|
goto _0
|
|
_3:
|
|
_worker_close_connection(tls, _p)
|
|
crt.Xprintf(tls, str(1552), _p.X0)
|
|
crt.Xfflush(tls, (*crt.XFILE)(Xstdout))
|
|
return nil
|
|
}
|
|
|
|
// Open the database connection for WorkerInfo. The order in which
|
|
// the files are opened is a function of the tid value.
|
|
func _worker_open_connection(tls *crt.TLS, _p *XWorkerInfo, _iCnt int32) {
|
|
var _x, _rc int32
|
|
var _zFile *int8
|
|
_x = ((_p.X0) + _iCnt) % i32(6)
|
|
_zFile = bin.Xsqlite3_mprintf(tls, str(1572), int32(*(*uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)((*[3]uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)(&_worker_open_connectionØ00aOrderØ001))+3*uintptr(_x))))) + 1*uintptr(i32(0))))))
|
|
_check_oom(tls, (unsafe.Pointer)(_zFile))
|
|
_worker_trace(tls, _p, str(1586), unsafe.Pointer(_zFile))
|
|
_rc = bin.Xsqlite3_open_v2(tls, _zFile, (**bin.Xsqlite3)(unsafe.Pointer((*unsafe.Pointer)(unsafe.Pointer(&(_p.X4))))), i32(131074), nil)
|
|
if _rc != i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(1594), unsafe.Pointer(_zFile), _p.X0)
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zFile))
|
|
_run_sql(tls, _p, str(1634))
|
|
bin.Xsqlite3_busy_timeout(tls, (*bin.Xsqlite3)(_p.X4), i32(10000))
|
|
_run_sql(tls, _p, str(1662))
|
|
_run_sql(tls, _p, str(1686), int32(*(*uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)((*[3]uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)(&_worker_open_connectionØ00aOrderØ001))+3*uintptr(_x))))) + 1*uintptr(i32(1))))))
|
|
_run_sql(tls, _p, str(1717), int32(*(*uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)((*[3]uint8)(unsafe.Pointer(uintptr((unsafe.Pointer)(&_worker_open_connectionØ00aOrderØ001))+3*uintptr(_x))))) + 1*uintptr(i32(2))))))
|
|
}
|
|
|
|
var _worker_open_connectionØ00aOrderØ001 [6][3]uint8
|
|
|
|
func init() {
|
|
_worker_open_connectionØ00aOrderØ001 = [6][3]uint8{[3]uint8{u8(1), u8(2), u8(3)}, [3]uint8{u8(1), u8(3), u8(2)}, [3]uint8{u8(2), u8(1), u8(3)}, [3]uint8{u8(2), u8(3), u8(1)}, [3]uint8{u8(3), u8(1), u8(2)}, [3]uint8{u8(3), u8(2), u8(1)}}
|
|
}
|
|
|
|
// Create rows mn through mx in table iTab for the given worker
|
|
func _worker_add_content(tls *crt.TLS, _p *XWorkerInfo, _mn int32, _mx int32, _iTab int32) {
|
|
var _zTabDef *int8
|
|
switch _iTab {
|
|
case i32(1):
|
|
goto _1
|
|
case i32(2):
|
|
goto _2
|
|
case i32(3):
|
|
goto _3
|
|
default:
|
|
goto _4
|
|
}
|
|
|
|
_1:
|
|
_zTabDef = str(1748)
|
|
goto _4
|
|
_2:
|
|
_zTabDef = str(1765)
|
|
goto _4
|
|
_3:
|
|
_zTabDef = str(1782)
|
|
goto _4
|
|
_4:
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1799), _mn, _mx, unsafe.Pointer(_zTabDef), _p.X0)
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
}
|
|
|
|
// Prepare a single SQL query
|
|
func _prep_sql(tls *crt.TLS, _db unsafe.Pointer, _zFormat *int8, args ...interface{}) (r0 unsafe.Pointer) {
|
|
var _rc int32
|
|
var _zSql *int8
|
|
var _pStmt unsafe.Pointer
|
|
var _ap []interface{}
|
|
_pStmt = nil
|
|
_ap = args
|
|
_zSql = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_ap = nil
|
|
_check_oom(tls, (unsafe.Pointer)(_zSql))
|
|
_rc = bin.Xsqlite3_prepare_v2(tls, (*bin.Xsqlite3)(_db), _zSql, i32(-1), &_pStmt, nil)
|
|
if _rc != i32(0) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstderr), str(991), _rc, bin.Xsqlite3_extended_errcode(tls, (*bin.Xsqlite3)(_db)), unsafe.Pointer(bin.Xsqlite3_errmsg(tls, (*bin.Xsqlite3)(_db))), unsafe.Pointer(_zSql))
|
|
crt.Xexit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zSql))
|
|
return _pStmt
|
|
}
|
|
|
|
// Set an error message on a worker
|
|
func _worker_error(tls *crt.TLS, _p *XWorkerInfo, _zFormat *int8, args ...interface{}) {
|
|
var _ap []interface{}
|
|
*(*int32)(unsafe.Pointer(&(_p.X5))) += 1
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_p.X7))
|
|
_ap = args
|
|
*(**int8)(unsafe.Pointer(&(_p.X7))) = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_ap = nil
|
|
}
|
|
|
|
// Delete all content in the three databases associated with a
|
|
// single thread. Make this happen all in a single transaction if
|
|
// inTrans is true, or separately for each database if inTrans is
|
|
// false.
|
|
func _worker_delete_all_content(tls *crt.TLS, _p *XWorkerInfo, _inTrans int32) {
|
|
if _inTrans != 0 {
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1947))
|
|
_run_sql(tls, _p, str(1953), _p.X0)
|
|
_run_sql(tls, _p, str(1981), _p.X0)
|
|
_run_sql(tls, _p, str(2009), _p.X0)
|
|
_run_sql(tls, _p, str(2037))
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
goto _1
|
|
}
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1953), _p.X0)
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(1981), _p.X0)
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
crt.Xpthread_mutex_lock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
_run_sql(tls, _p, str(2009), _p.X0)
|
|
crt.Xpthread_mutex_unlock(tls, (*crt.Xpthread_mutex_t)(_p.X9))
|
|
*(*int32)(unsafe.Pointer(&(_p.X6))) += 1
|
|
_1:
|
|
}
|
|
|
|
// Close the worker database connection
|
|
func _worker_close_connection(tls *crt.TLS, _p *XWorkerInfo) {
|
|
if (_p.X4) != nil {
|
|
_worker_trace(tls, _p, str(2044))
|
|
bin.Xsqlite3_close(tls, (*bin.Xsqlite3)(_p.X4))
|
|
*(*unsafe.Pointer)(unsafe.Pointer(&(_p.X4))) = nil
|
|
}
|
|
}
|
|
|
|
func bool2int(b bool) int32 {
|
|
if b {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
func bug20530(interface{}) {} //TODO remove when https://github.com/golang/go/issues/20530 is fixed.
|
|
func i16(n int16) int16 { return n }
|
|
func i32(n int32) int32 { return n }
|
|
func i64(n int64) int64 { return n }
|
|
func i8(n int8) int8 { return n }
|
|
func init() { nzf32 *= -1; nzf64 *= -1 }
|
|
func u16(n uint16) uint16 { return n }
|
|
func u32(n uint32) uint32 { return n }
|
|
func u64(n uint64) uint64 { return n }
|
|
func u8(n byte) byte { return n }
|
|
|
|
var inf = math.Inf(1)
|
|
var nzf32 float32 // -0.0
|
|
var nzf64 float64 // -0.0
|
|
func sink1(int32) {} //TODO report GC bug
|
|
func sink0(uint32) {} //TODO report GC bug
|
|
func store1(p *int32, v int32) int32 { *p = v; return v }
|
|
|
|
type XWorkerInfo struct {
|
|
X0 int32
|
|
X1 int32
|
|
X2 uint32
|
|
X3 unsafe.Pointer
|
|
X4 unsafe.Pointer
|
|
X5 int32
|
|
X6 int32
|
|
X7 *int8
|
|
X8 uint32
|
|
X9 unsafe.Pointer
|
|
} // t2 struct{int32,int32,uint32,*struct{},*struct{},int32,int32,*int8,uint32,*struct{}}
|
|
func str(n int) *int8 { return (*int8)(unsafe.Pointer(&strTab[n])) }
|
|
func wstr(n int) *int32 { return (*int32)(unsafe.Pointer(&strTab[n])) }
|
|
|
|
var strTab = []byte("-multithread\x00-serialized\x00-wal\x00-trace\x00unknown command-line option: %s\x0a\x00minimum of 2 threads\x0a\x00extra command-line argument: \"%s\"\x0a\x00usage: %s ?OPTIONS? N\x0aN is the number of threads and must be at least 2.\x0aOptions:\x0a --serialized\x0a --multithread\x0a --wal\x0a --trace\x0a\x00requires a threadsafe build of SQLite\x0a\x00tt4-test1.db\x00tt4-test2.db\x00tt4-test3.db\x00Unable to open test database: tt4-test2.db\x0a\x00PRAGMA journal_mode=WAL\x00PRAGMA synchronous=OFF\x00CREATE TABLE IF NOT EXISTS t1(tid INTEGER, sp, a, b, c)\x00CREATE INDEX t1tid ON t1(tid)\x00CREATE INDEX t1ab ON t1(a,b)\x00ATTACH 'tt4-test2.db' AS 'test2'\x00CREATE TABLE IF NOT EXISTS test2.t2(tid INTEGER, sp, d, e, f)\x00CREATE INDEX test2.t2tid ON t2(tid)\x00CREATE INDEX test2.t2de ON t2(d,e)\x00ATTACH 'tt4-test3.db' AS 'test3'\x00CREATE TABLE IF NOT EXISTS test3.t3(tid INTEGER, sp, x, y, z)\x00CREATE INDEX test3.t3tid ON t3(tid)\x00CREATE INDEX test3.t3xy ON t3(x,y)\x00thread creation failed for thread %d\x0a\x00Joined thread %d: %d errors in %d tests\x00: %s\x0a\x00\x0a\x00Total %d errors in %d tests\x0a\x00SQL error (%d,%d): %s\x0aWhile preparing: [%s]\x0a\x00running [%s]\x00retry %d for [%s]\x00Deadlock in thread %d while running [%s]\x0a\x00SQL error (%d,%d): %s\x0aWhile running [%s]\x0a\x00out of memory\x0a\x00TRACE(%02d): %s\x0a\x00worker %d startup\x0a\x00SELECT count(a) FROM t1 WHERE tid=%d\x00query [%s]\x00Failed to step: %s\x00Wrong result: %d\x00BEGIN;\x00UPDATE t1 SET c=NULL WHERE a=55\x00UPDATE t2 SET f=NULL WHERE d=42\x00UPDATE t3 SET z=NULL WHERE x=31\x00ROLLBACK;\x00VACUUM\x00SELECT t1.rowid, t2.rowid, t3.rowid FROM t1, t2, t3 WHERE t1.tid=%d AND t2.tid=%d AND t3.tid=%d AND t1.a<>t2.d AND t2.d<>t3.x ORDER BY 1, 2, 3\x00worker %d finished\x0a\x00tt4-test%d.db\x00open %s\x00sqlite_open_v2(%s) failed on thread %d\x0a\x00PRAGMA read_uncommitted=ON;\x00PRAGMA synchronous=OFF;\x00ATTACH 'tt4-test%d.db' AS aux1\x00ATTACH 'tt4-test%d.db' AS aux2\x00t1(tid,sp,a,b,c)\x00t2(tid,sp,d,e,f)\x00t3(tid,sp,x,y,z)\x00WITH RECURSIVE\x0a c(i) AS (VALUES(%d) UNION ALL SELECT i+1 FROM c WHERE i<%d)\x0aINSERT INTO %s SELECT %d, zeroblob(3000), i, printf('%%d',i), i FROM c;\x00BEGIN\x00DELETE FROM t1 WHERE tid=%d\x00DELETE FROM t2 WHERE tid=%d\x00DELETE FROM t3 WHERE tid=%d\x00COMMIT\x00close\x00")
|