mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-05 15:56:52 +08:00

modified: generator.go modified: internal/bin/bin_linux_amd64.go modified: internal/mptest/mptest_linux_amd64.go new file: internal/sqlite.org/sqlite-src-3190300/test/threadtest1.c modified: internal/threadtest1/threadtest1_linux_amd64.go modified: internal/threadtest2/threadtest2_linux_amd64.go modified: internal/threadtest3/threadtest3_linux_amd64.go modified: z_linux_test.go
422 lines
13 KiB
Go
422 lines
13 KiB
Go
// Code generated by ccgo. DO NOT EDIT.
|
|
|
|
// threadtest1.c
|
|
|
|
// 2002 January 15
|
|
//
|
|
// 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 test whether
|
|
// or not the SQLite library is threadsafe.
|
|
//
|
|
// Testing the thread safety of SQLite is difficult because there are very
|
|
// few places in the code that are even potentially unsafe, and those
|
|
// places execute for very short periods of time. So even if the library
|
|
// is compiled with its mutexes disabled, it is likely to work correctly
|
|
// in a multi-threaded program most of the time.
|
|
//
|
|
// This file is NOT part of the standard SQLite library. It is used for
|
|
// testing only.
|
|
|
|
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)) + 8)
|
|
}
|
|
|
|
var Xstderr unsafe.Pointer
|
|
|
|
func init() {
|
|
Xstderr = (unsafe.Pointer)(uintptr(unsafe.Pointer(&X__stdfiles)) + 16)
|
|
}
|
|
|
|
func Xmain(tls *crt.TLS, _argc int32, _argv **int8) (r0 int32) {
|
|
var _i, _n int32
|
|
var _id uint64
|
|
var _zFile, _4_zDb, _4_zJournal *int8
|
|
var _2_zBuf, _6_zBuf [200]int8
|
|
r0 = i32(0)
|
|
if (_argc > i32(2)) && (crt.Xstrcmp(tls, *(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 8*uintptr(i32(1)))), str(0)) == i32(0)) {
|
|
_verbose = i32(1)
|
|
bug20530(_verbose)
|
|
_argc -= 1
|
|
*(*uintptr)(unsafe.Pointer(&_argv)) += uintptr(8)
|
|
}
|
|
if (_argc < i32(2)) || (store0(&_n, crt.Xatoi(tls, *(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_argv)) + 8*uintptr(i32(1)))))) < i32(1)) {
|
|
_n = i32(10)
|
|
}
|
|
_i = i32(0)
|
|
_4:
|
|
if _i >= _n {
|
|
goto _7
|
|
}
|
|
crt.Xsprintf(tls, (*int8)(unsafe.Pointer(&_2_zBuf)), str(3), (_i+i32(1))/i32(2))
|
|
crt.Xunlink(tls, (*int8)(unsafe.Pointer(&_2_zBuf)))
|
|
_i += 1
|
|
goto _4
|
|
_7:
|
|
_i = i32(0)
|
|
_8:
|
|
if _i >= _n {
|
|
goto _11
|
|
}
|
|
_zFile = bin.Xsqlite3_mprintf(tls, str(13), (_i%i32(2))+i32(1), (_i+i32(2))/i32(2))
|
|
if (_i % i32(2)) == i32(0) {
|
|
_4_zDb = (*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_zFile)) + 1*uintptr(i32(2))))
|
|
_4_zJournal = bin.Xsqlite3_mprintf(tls, str(26), unsafe.Pointer(_4_zDb))
|
|
crt.Xunlink(tls, _4_zDb)
|
|
crt.Xunlink(tls, _4_zJournal)
|
|
crt.Xfree(tls, (unsafe.Pointer)(_4_zJournal))
|
|
}
|
|
crt.Xpthread_create(tls, &_id, nil, _worker_bee, (unsafe.Pointer)(_zFile))
|
|
crt.Xpthread_detach(tls, _id)
|
|
_i += 1
|
|
goto _8
|
|
_11:
|
|
crt.Xpthread_mutex_lock(tls, &Xlock)
|
|
_13:
|
|
if Xthread_cnt > i32(0) {
|
|
crt.Xpthread_cond_wait(tls, &Xsig, &Xlock)
|
|
goto _13
|
|
}
|
|
crt.Xpthread_mutex_unlock(tls, &Xlock)
|
|
_i = i32(0)
|
|
_15:
|
|
if _i >= _n {
|
|
goto _18
|
|
}
|
|
crt.Xsprintf(tls, (*int8)(unsafe.Pointer(&_6_zBuf)), str(3), (_i+i32(1))/i32(2))
|
|
crt.Xunlink(tls, (*int8)(unsafe.Pointer(&_6_zBuf)))
|
|
_i += 1
|
|
goto _15
|
|
_18:
|
|
return i32(0)
|
|
|
|
_ = _2_zBuf
|
|
_ = _6_zBuf
|
|
panic(0)
|
|
}
|
|
|
|
var _verbose int32
|
|
|
|
func _worker_bee(tls *crt.TLS, _pArg unsafe.Pointer) (r0 unsafe.Pointer) {
|
|
var _i, _cnt, _t int32
|
|
var _zFilename, _azErr *int8
|
|
var _db unsafe.Pointer
|
|
var _az **int8
|
|
var _4_z1, _4_z2 [30]int8
|
|
_zFilename = (*int8)(_pArg)
|
|
_t = crt.Xatoi(tls, _zFilename)
|
|
crt.Xpthread_mutex_lock(tls, &Xlock)
|
|
Xthread_cnt += 1
|
|
crt.Xpthread_mutex_unlock(tls, &Xlock)
|
|
crt.Xprintf(tls, str(37), unsafe.Pointer(_zFilename))
|
|
crt.Xfflush(tls, (*crt.XFILE)(Xstdout))
|
|
_cnt = i32(0)
|
|
_0:
|
|
if _cnt >= i32(10) {
|
|
goto _3
|
|
}
|
|
bin.Xsqlite3_open(tls, (*int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_zFilename))+1*uintptr(i32(2)))), (**bin.Xsqlite3)(unsafe.Pointer(&_db)))
|
|
if _db == nil {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstdout), str(48), unsafe.Pointer(_zFilename))
|
|
_Exit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_busy_handler(tls, (*bin.Xsqlite3)(_db), _db_is_locked, (unsafe.Pointer)(_zFilename))
|
|
Xdb_execute(tls, _db, _zFilename, str(64), _t)
|
|
_i = i32(1)
|
|
_5:
|
|
if _i > i32(100) {
|
|
goto _8
|
|
}
|
|
Xdb_execute(tls, _db, _zFilename, str(89), _t, _i, _i*i32(2), _i*_i)
|
|
_i += 1
|
|
goto _5
|
|
_8:
|
|
_az = Xdb_query(tls, _db, _zFilename, str(123), _t)
|
|
Xdb_check(tls, _zFilename, str(148), _az, unsafe.Pointer(str(156)), i32(0))
|
|
_az = Xdb_query(tls, _db, _zFilename, str(160), _t)
|
|
Xdb_check(tls, _zFilename, str(183), _az, unsafe.Pointer(str(190)), i32(0))
|
|
Xdb_execute(tls, _db, _zFilename, str(196), _t)
|
|
_az = Xdb_query(tls, _db, _zFilename, str(160), _t)
|
|
Xdb_check(tls, _zFilename, str(223), _az, unsafe.Pointer(str(231)), i32(0))
|
|
_i = i32(1)
|
|
_9:
|
|
if _i > i32(50) {
|
|
goto _12
|
|
}
|
|
_az = Xdb_query(tls, _db, _zFilename, str(236), _t, _i)
|
|
crt.Xsprintf(tls, (*int8)(unsafe.Pointer(&_4_z1)), str(268), _i*i32(2))
|
|
crt.Xsprintf(tls, (*int8)(unsafe.Pointer(&_4_z2)), str(268), _i*_i)
|
|
Xdb_check(tls, _zFilename, str(271), _az, unsafe.Pointer((*int8)(unsafe.Pointer(&_4_z1))), unsafe.Pointer((*int8)(unsafe.Pointer(&_4_z2))), i32(0))
|
|
_i += 1
|
|
goto _9
|
|
_12:
|
|
Xdb_execute(tls, _db, _zFilename, str(280), _t)
|
|
bin.Xsqlite3_close(tls, (*bin.Xsqlite3)(_db))
|
|
_cnt += 1
|
|
goto _0
|
|
_3:
|
|
crt.Xprintf(tls, str(296), unsafe.Pointer(_zFilename))
|
|
crt.Xfflush(tls, (*crt.XFILE)(Xstdout))
|
|
crt.Xpthread_mutex_lock(tls, &Xlock)
|
|
Xthread_cnt -= 1
|
|
if Xthread_cnt <= i32(0) {
|
|
crt.Xpthread_cond_signal(tls, &Xsig)
|
|
}
|
|
crt.Xpthread_mutex_unlock(tls, &Xlock)
|
|
return nil
|
|
|
|
_ = _azErr
|
|
_ = _4_z1
|
|
_ = _4_z2
|
|
panic(0)
|
|
}
|
|
|
|
var Xlock crt.Xpthread_mutex_t
|
|
|
|
var Xthread_cnt int32
|
|
|
|
// Come here to die.
|
|
func _Exit(tls *crt.TLS, _rc int32) {
|
|
crt.Xexit(tls, _rc)
|
|
}
|
|
|
|
// When a lock occurs, yield.
|
|
func _db_is_locked(tls *crt.TLS, _NotUsed unsafe.Pointer, _iCount int32) (r0 int32) {
|
|
if _verbose != 0 {
|
|
crt.Xprintf(tls, str(305), unsafe.Pointer((*int8)(_NotUsed)), _iCount)
|
|
}
|
|
crt.Xusleep(tls, uint32(i32(100)))
|
|
return bool2int(_iCount < i32(20000))
|
|
}
|
|
|
|
// Execute an SQL statement.
|
|
func Xdb_execute(tls *crt.TLS, _db unsafe.Pointer, _zFile *int8, _zFormat *int8, args ...interface{}) {
|
|
var _rc int32
|
|
var _zSql, _zErrMsg *int8
|
|
var _ap []interface{}
|
|
_zErrMsg = nil
|
|
_ap = args
|
|
_zSql = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_ap = nil
|
|
if _verbose != 0 {
|
|
crt.Xprintf(tls, str(318), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql))
|
|
}
|
|
_0:
|
|
_rc = bin.Xsqlite3_exec(tls, (*bin.Xsqlite3)(_db), _zSql, nil, nil, &_zErrMsg)
|
|
if _rc == i32(5) {
|
|
goto _0
|
|
}
|
|
if _verbose != 0 {
|
|
crt.Xprintf(tls, str(331), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql))
|
|
}
|
|
if _zErrMsg != nil {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstdout), str(344), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql), unsafe.Pointer(_zErrMsg))
|
|
crt.Xfree(tls, (unsafe.Pointer)(_zErrMsg))
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zSql))
|
|
_Exit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zSql))
|
|
}
|
|
|
|
// Execute a query against the database. NULL values are returned
|
|
// as an empty string. The list is terminated by a single NULL pointer.
|
|
func Xdb_query(tls *crt.TLS, _db unsafe.Pointer, _zFile *int8, _zFormat *int8, args ...interface{}) (r0 **int8) {
|
|
var _rc int32
|
|
var _zSql, _zErrMsg *int8
|
|
var _ap []interface{}
|
|
var _sResult TQueryResult
|
|
_zErrMsg = nil
|
|
_ap = args
|
|
_zSql = bin.Xsqlite3_vmprintf(tls, _zFormat, _ap)
|
|
_ap = nil
|
|
crt.Xmemset(tls, (unsafe.Pointer)(&_sResult), i32(0), u64(24))
|
|
*(**int8)(unsafe.Pointer(&(_sResult.X0))) = _zFile
|
|
if _verbose != 0 {
|
|
crt.Xprintf(tls, str(373), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql))
|
|
}
|
|
_rc = bin.Xsqlite3_exec(tls, (*bin.Xsqlite3)(_db), _zSql, _db_query_callback, (unsafe.Pointer)(&_sResult), &_zErrMsg)
|
|
if _rc != i32(17) {
|
|
goto _1
|
|
}
|
|
if _zErrMsg != nil {
|
|
crt.Xfree(tls, (unsafe.Pointer)(_zErrMsg))
|
|
}
|
|
_rc = bin.Xsqlite3_exec(tls, (*bin.Xsqlite3)(_db), _zSql, _db_query_callback, (unsafe.Pointer)(&_sResult), &_zErrMsg)
|
|
_1:
|
|
if _verbose != 0 {
|
|
crt.Xprintf(tls, str(387), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql))
|
|
}
|
|
if _zErrMsg != nil {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstdout), str(399), unsafe.Pointer(_zFile), unsafe.Pointer(_zSql), unsafe.Pointer(_zErrMsg))
|
|
crt.Xfree(tls, (unsafe.Pointer)(_zErrMsg))
|
|
crt.Xfree(tls, (unsafe.Pointer)(_zSql))
|
|
_Exit(tls, i32(1))
|
|
}
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(_zSql))
|
|
if (_sResult.X3) == nil {
|
|
_db_query_callback(tls, (unsafe.Pointer)(&_sResult), i32(0), nil, nil)
|
|
}
|
|
*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_sResult.X3)) + 8*uintptr(_sResult.X1))) = nil
|
|
return _sResult.X3
|
|
|
|
_ = _sResult
|
|
panic(0)
|
|
}
|
|
|
|
// The callback function for db_query
|
|
func _db_query_callback(tls *crt.TLS, _pUser unsafe.Pointer, _nArg int32, _azArg **int8, _NotUsed **int8) (r0 int32) {
|
|
var _i int32
|
|
var _pResult *TQueryResult
|
|
_pResult = (*TQueryResult)(_pUser)
|
|
if ((_pResult.X1) + _nArg) < (_pResult.X2) {
|
|
goto _0
|
|
}
|
|
if (_pResult.X2) == i32(0) {
|
|
*(*int32)(unsafe.Pointer(&(_pResult.X2))) = _nArg + i32(1)
|
|
goto _2
|
|
}
|
|
*(*int32)(unsafe.Pointer(&(_pResult.X2))) = (((_pResult.X2) * i32(2)) + _nArg) + i32(1)
|
|
_2:
|
|
*(***int8)(unsafe.Pointer(&(_pResult.X3))) = (**int8)(crt.Xrealloc(tls, (unsafe.Pointer)(_pResult.X3), uint64(_pResult.X2)*u64(8)))
|
|
if (_pResult.X3) == nil {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstdout), str(426), unsafe.Pointer(_pResult.X0))
|
|
return i32(1)
|
|
}
|
|
_0:
|
|
if _azArg == nil {
|
|
return i32(0)
|
|
}
|
|
_i = i32(0)
|
|
_5:
|
|
if _i >= _nArg {
|
|
goto _8
|
|
}
|
|
*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_pResult.X3)) + 8*uintptr(postInc0((*int32)(unsafe.Pointer(&(_pResult.X1))), int32(1))))) = bin.Xsqlite3_mprintf(tls, str(445), unsafe.Pointer(func() *int8 {
|
|
if (*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_azArg)) + 8*uintptr(_i)))) != nil {
|
|
return (*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_azArg)) + 8*uintptr(_i))))
|
|
}
|
|
return str(448)
|
|
}()))
|
|
_i += 1
|
|
goto _5
|
|
_8:
|
|
return i32(0)
|
|
}
|
|
|
|
// Check results
|
|
func Xdb_check(tls *crt.TLS, _zFile *int8, _zMsg *int8, _az **int8, args ...interface{}) {
|
|
var _i int32
|
|
var _z *int8
|
|
var _ap []interface{}
|
|
_ap = args
|
|
_i = i32(0)
|
|
_0:
|
|
if store1(&_z, (*int8)(crt.VAPointer(&_ap))) == nil {
|
|
goto _3
|
|
}
|
|
if ((*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_az)) + 8*uintptr(_i)))) == nil) || (crt.Xstrcmp(tls, *(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_az)) + 8*uintptr(_i))), _z) != i32(0)) {
|
|
crt.Xfprintf(tls, (*crt.XFILE)(Xstdout), str(449), unsafe.Pointer(_zFile), unsafe.Pointer(_zMsg), _i+i32(1), unsafe.Pointer(*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_az)) + 8*uintptr(_i)))))
|
|
Xdb_query_free(tls, _az)
|
|
_Exit(tls, i32(1))
|
|
}
|
|
_i += 1
|
|
goto _0
|
|
_3:
|
|
_ap = nil
|
|
Xdb_query_free(tls, _az)
|
|
}
|
|
|
|
// Free the results of a db_query() call.
|
|
func Xdb_query_free(tls *crt.TLS, _az **int8) {
|
|
var _i int32
|
|
_i = i32(0)
|
|
_0:
|
|
if (*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_az)) + 8*uintptr(_i)))) == nil {
|
|
goto _3
|
|
}
|
|
bin.Xsqlite3_free(tls, (unsafe.Pointer)(*(**int8)(unsafe.Pointer(uintptr((unsafe.Pointer)(_az)) + 8*uintptr(_i)))))
|
|
_i += 1
|
|
goto _0
|
|
_3:
|
|
crt.Xfree(tls, (unsafe.Pointer)(_az))
|
|
}
|
|
|
|
var Xsig crt.Xpthread_cond_t
|
|
|
|
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 postInc0(p *int32, d int32) int32 { v := *p; *p += d; return v }
|
|
func store1(p **int8, v *int8) *int8 { *p = v; return v }
|
|
func store0(p *int32, v int32) int32 { *p = v; return v }
|
|
|
|
type TQueryResult struct {
|
|
X0 *int8
|
|
X1 int32
|
|
X2 int32
|
|
X3 **int8
|
|
} // t2 struct{*int8,int32,int32,**int8}
|
|
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("-v\x00testdb-%d\x00%d.testdb-%d\x00%s-journal\x00%s: START\x0a\x00%s: can't open\x0a\x00CREATE TABLE t%d(a,b,c);\x00INSERT INTO t%d VALUES(%d,%d,%d);\x00SELECT count(*) FROM t%d\x00tX size\x00100\x00SELECT avg(b) FROM t%d\x00tX avg\x00101.0\x00DELETE FROM t%d WHERE a>50\x00tX avg2\x0051.0\x00SELECT b, c FROM t%d WHERE a=%d\x00%d\x00readback\x00DROP TABLE t%d;\x00%s: END\x0a\x00BUSY %s #%d\x0a\x00EXEC %s: %s\x0a\x00DONE %s: %s\x0a\x00%s: command failed: %s - %s\x0a\x00QUERY %s: %s\x0a\x00DONE %s %s\x0a\x00%s: query failed: %s - %s\x0a\x00%s: malloc failed\x0a\x00%s\x00\x00%s: %s: bad result in column %d: %s\x0a\x00")
|