瀏覽代碼

codec: make uncommon path in basicHandle() noinline

Also clean up build.sh to remove references to external and other
extraneous items.
Ugorji Nwoke 6 年之前
父節點
當前提交
b47423764d
共有 3 個文件被更改,包括 22 次插入17 次删除
  1. 0 0
      codec/0_doc.go
  2. 5 8
      codec/build.sh
  3. 17 9
      codec/helper.go

+ 0 - 0
codec/0doc.go → codec/0_doc.go


+ 5 - 8
codec/build.sh

@@ -146,7 +146,7 @@ _codegenerators() {
 }
 }
 
 
 _prebuild() {
 _prebuild() {
-    echo "prebuild: zforce: $zforce , zexternal: $zexternal"
+    echo "prebuild: zforce: $zforce"
     zmydir=`pwd`
     zmydir=`pwd`
     zfin="test_values.generated.go"
     zfin="test_values.generated.go"
     zfin2="test_values_flex.generated.go"
     zfin2="test_values_flex.generated.go"
@@ -168,9 +168,8 @@ _prebuild() {
 
 
 _make() {
 _make() {
     zforce=1
     zforce=1
-    zexternal=1
     (cd codecgen && go install ${zargs[*]} .) && _prebuild && go install ${zargs[*]} .
     (cd codecgen && go install ${zargs[*]} .) && _prebuild && go install ${zargs[*]} .
-    unset zforce zexternal
+    unset zforce
 }
 }
 
 
 _clean() {
 _clean() {
@@ -227,15 +226,14 @@ EOF
 _main() {
 _main() {
     if [[ -z "$1" ]]; then _usage; return 1; fi
     if [[ -z "$1" ]]; then _usage; return 1; fi
     local x
     local x
-    unset zforce zexternal
+    unset zforce
     zargs=()
     zargs=()
     zbenchflags=""
     zbenchflags=""
     OPTIND=1
     OPTIND=1
-    while getopts ":ctmnrgupfvxlzdb:" flag
+    while getopts ":ctmnrgpfvlzdb:" flag
     do
     do
         case "x$flag" in
         case "x$flag" in
             'xf') zforce=1 ;;
             'xf') zforce=1 ;;
-            'xx') zexternal=1 ;;
             'xv') zverbose=1 ;;
             'xv') zverbose=1 ;;
             'xl') zargs+=("-gcflags"); zargs+=("-l=4") ;;
             'xl') zargs+=("-gcflags"); zargs+=("-l=4") ;;
             'xn') zargs+=("-gcflags"); zargs+=("-m=2") ;;
             'xn') zargs+=("-gcflags"); zargs+=("-m=2") ;;
@@ -252,13 +250,12 @@ _main() {
         'xm') _make "$@" ;;
         'xm') _make "$@" ;;
         'xr') _release "$@" ;;
         'xr') _release "$@" ;;
         'xg') _go ;;
         'xg') _go ;;
-        'xu') _githubupdate ;;
         'xp') _prebuild "$@" ;;
         'xp') _prebuild "$@" ;;
         'xc') _clean "$@" ;;
         'xc') _clean "$@" ;;
         'xz') _analyze "$@" ;;
         'xz') _analyze "$@" ;;
         'xb') _bench "$@" ;;
         'xb') _bench "$@" ;;
     esac
     esac
-    unset zforce zexternal 
+    unset zforce
 }
 }
 
 
 [ "." = `dirname $0` ] && _main "$@"
 [ "." = `dirname $0` ] && _main "$@"

+ 17 - 9
codec/helper.go

@@ -590,20 +590,28 @@ func basicHandle(hh Handle) (x *BasicHandle) {
 	// 	x.n = hh.Name()[0]
 	// 	x.n = hh.Name()[0]
 	// }
 	// }
 
 
-	// simulate once.Do using our own stored flag and mutex
+	// simulate once.Do using our own stored flag and mutex as a CompareAndSwap
+	// is not sufficient, since a race condition can occur within init(Handle) function.
+	// init is made noinline, so that this function can be inlined by its caller.
 	if atomic.LoadUint32(&x.inited) == 0 {
 	if atomic.LoadUint32(&x.inited) == 0 {
-		x.mu.Lock()
-		if x.inited == 0 {
-			x.be = hh.isBinary()
-			_, x.js = hh.(*JsonHandle)
-			x.n = hh.Name()[0]
-			atomic.StoreUint32(&x.inited, 1)
-		}
-		x.mu.Unlock()
+		x.init(hh)
 	}
 	}
 	return
 	return
 }
 }
 
 
+//go:noinline
+func (x *BasicHandle) init(hh Handle) {
+	// make it uninlineable, as it is called at most once
+	x.mu.Lock()
+	if x.inited == 0 {
+		x.be = hh.isBinary()
+		_, x.js = hh.(*JsonHandle)
+		x.n = hh.Name()[0]
+		atomic.StoreUint32(&x.inited, 1)
+	}
+	x.mu.Unlock()
+}
+
 func (x *BasicHandle) getBasicHandle() *BasicHandle {
 func (x *BasicHandle) getBasicHandle() *BasicHandle {
 	return x
 	return x
 }
 }