Bug 16436 - inconsistent behavior when using ThreadStaticAttribute with ValueType
Summary: inconsistent behavior when using ThreadStaticAttribute with ValueType
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: GC ()
Version: 2.10.x
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-11-25 09:02 UTC by Hzj_jie
Modified: 2013-11-27 10:09 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
gzip + tar, with source codes of vb.net and c#, and compiled binary files (5.08 KB, application/x-gzip)
2013-11-25 09:02 UTC, Hzj_jie
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Hzj_jie 2013-11-25 09:02:55 UTC
Created attachment 5528 [details]
gzip + tar, with source codes of vb.net and c#, and compiled binary files

when using ThreadStaticAttribute with ValueType, ie, struct, the behavior is inconsistent between mono-sgen and mono / .net.
briefly when using mono-sgen, the thread static value will be collected, while mono w/ boehm does not have the issue, and same as in .net. both c# and vb.net have the same issue.

following both vb.net and c# source code to trigger the issue.
vb.net, use compiling command as vbc /removeintchecks threadstaticvaluetype.vb

Imports System.Threading

Public Module Main
    Private Structure vt
        Public v() As Int32

        Public Sub init()
            If v Is Nothing Then
                ReDim v(100)
            End If
        End Sub
    End Structure

    <ThreadStatic> Private vto As vt

    Public Sub Main()
        For i As Int32 = 0 To 127
            ThreadPool.QueueUserWorkItem(Sub()
                                             Dim v As Int32 = 0
                                             Dim t As Int32 = 0
                                             While(True)
                                                 vto.init()
                                                 If t Mod 10000 = 0 Then
                                                     Randomize()
                                                     v = CInt(Rnd() * 100000)
                                                     vto.v(0) = v
                                                 End If
                                                 If vto.v Is Nothing OrElse vto.v.Length() = 0 OrElse vto.v(0) <> v Then
                                                     Console.WriteLine("bingo")
                                                 End If
                                                 t += 1
                                             End While
                                         End Sub)
        Next
        While(True)
            GC.WaitForPendingFinalizers()
            GC.Collect()
            Thread.Sleep(1000)
        End While
    End Sub
End Module

c#, use compiling command as csc /out:threadstaticvaluetype.cs.exe threadstaticvaluetype.cs

using System;
using System.Threading;

public static class program
{
    private struct vt
    {
        public int[] v;
        public void init()
        {
            if(v == null)
            {
                v = new int[100];
            }
        }
    }

    [ThreadStatic()] private static vt vto;

    public static void Main()
    {
        for(int i = 0; i < 128; i++)
        {
            ThreadPool.QueueUserWorkItem((NIU) =>
                    {
                        int v = 0;
                        int t = 0;
                        Random r = new Random();
                        while(true)
                        {
                            vto.init();
                            if(t % 10000 == 0)
                            {
                                v = r.Next();
                                vto.v[0] = v;
                            }
                            if(vto.v == null || vto.v.Length == 0 || vto.v[0] != v)
                            {
                                Console.WriteLine("bingo");
                            }
                            t++;
                        }
                    });
        }

        while(true)
        {
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Thread.Sleep(1000);
        }
    }
}

i am using .net 3.5 in my machine, but i trust the behavior is consistent between different .net versions.
and the binary files are attached, threadstaticvaluetype.exe is for vb.net version, threadstaticvaluetype.cs.exe is for c# version.
Comment 1 Zoltan Varga 2013-11-27 04:37:16 UTC
What mono version is this ? This is probably fixed by:
https://github.com/mono/mono/commit/90690f50363e534b534b36dd008acf91d097d696
which is not yet in any released mono version.
Comment 2 Hzj_jie 2013-11-27 10:09:48 UTC
thank you for your update.