This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / corlib / System.Threading / Thread.cs
index 0e3e0cbd127af3f843a80f903f79718073992c6b..911fb1dbe12b580ff072932e739627e97064edf5 100755 (executable)
 //   Dick Porter (dick@ximian.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
+// Copyright (C) 2004 Novell (http://www.novell.com)
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
 using System.Runtime.Remoting.Contexts;
+using System.Security.Permissions;
 using System.Security.Principal;
 using System.Globalization;
 using System.Runtime.CompilerServices;
+using System.Collections;
 
 namespace System.Threading
 {
        public sealed class Thread
        {
+               #region Sync with object.h
+               // stores a thread handle
+               private IntPtr system_thread_handle;
+               
+               private CultureInfo current_culture;
+               private CultureInfo current_ui_culture;
+               private bool threadpool_thread;
+               /* accessed only from unmanaged code */
+               private IntPtr name;
+               private int name_len; 
+               private ThreadState state = ThreadState.Unstarted;
+               private object abort_exc;
+               internal object abort_state;
+               /* thread_id is only accessed from unmanaged code */
+               private int thread_id;
+               
+               /* start_notify is used by the runtime to signal that Start()
+                * is ok to return
+                */
+               private IntPtr start_notify;
+               private IntPtr stack_ptr;
+               private IntPtr static_data;
+               private IntPtr jit_data;
+               private IntPtr lock_data;
+               private IntPtr appdomain_refs;
+               private bool interruption_requested;
+               private IntPtr suspend_event;
+               private IntPtr resume_event;
+               private object synch_lock = new Object();
+               #endregion
+
+               private ThreadStart threadstart;
+               private string thread_name=null;
+               
+               private IPrincipal _principal;
+               
                public static Context CurrentContext {
                        get {
-                               // FIXME -
-                               // System.Runtime.Remoting.Context not
-                               // yet implemented
-                               return(null);
+                               return(AppDomain.InternalGetContext ());
                        }
                }
 
                public static IPrincipal CurrentPrincipal {
                        get {
-                               // FIXME -
-                               // System.Security.Principal.IPrincipal
-                               // not yet implemented
-                               return(null);
+                               IPrincipal p = null;
+                               Thread th = CurrentThread;
+                               lock (th) {
+                                       p = th._principal;
+                                       if (p == null) {
+                                               p = GetDomain ().DefaultPrincipal;
+                                               th._principal = p;
+                                       }
+                               }
+                               return p;
                        }
-                       
                        set {
+                               new SecurityPermission (SecurityPermissionFlag.ControlPrincipal).Demand ();
+                               CurrentThread._principal = value;
                        }
                }
 
@@ -47,115 +113,174 @@ namespace System.Threading
                        }
                }
 
+               internal static int CurrentThreadId {
+                       get {
+                               return CurrentThread.thread_id;
+                       }
+               }
+
+               // Looks up the slot hash for the current thread
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern static Hashtable SlotHash_lookup();
+
+               // Stores the slot hash for the current thread
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern static void SlotHash_store(Hashtable slothash);
+
+               private static Hashtable GetTLSSlotHash() {
+                       Hashtable slothash=SlotHash_lookup();
+                       if(slothash==null) {
+                               // Not synchronised, because this is
+                               // thread specific anyway.
+                               slothash=new Hashtable();
+                               SlotHash_store(slothash);
+                       }
+
+                       return(slothash);
+               }
+               
+               internal static object ResetDataStoreStatus () {
+                       Hashtable slothash=SlotHash_lookup();
+                       SlotHash_store(null);
+                       return slothash;
+               }
+
+               internal static void RestoreDataStoreStatus (object data) {
+                       SlotHash_store((Hashtable)data);
+               }
+
                public static LocalDataStoreSlot AllocateDataSlot() {
-                       // FIXME
-                       return(null);
+                       LocalDataStoreSlot slot = new LocalDataStoreSlot();
+
+                       return(slot);
                }
 
+               // Stores a hash keyed by strings of LocalDataStoreSlot objects
+               static Hashtable datastorehash;
+               private static object datastore_lock = new object ();
+               
+               private static void InitDataStoreHash () {
+                       lock (datastore_lock) {
+                               if (datastorehash == null) {
+                                       datastorehash = Hashtable.Synchronized(new Hashtable());
+                               }
+                       }
+               }
+               
                public static LocalDataStoreSlot AllocateNamedDataSlot(string name) {
-                       // FIXME
-                       return(null);
+                       lock (datastore_lock) {
+                               if (datastorehash == null)
+                                       InitDataStoreHash ();
+                               LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash[name];
+                               if(slot!=null) {
+                                       // This exception isnt documented (of
+                                       // course) but .net throws it
+                                       throw new ArgumentException("Named data slot already added");
+                               }
+                       
+                               slot = new LocalDataStoreSlot();
+
+                               datastorehash.Add(name, slot);
+
+                               return(slot);
+                       }
                }
 
                public static void FreeNamedDataSlot(string name) {
-                       // FIXME
+                       lock (datastore_lock) {
+                               if (datastorehash == null)
+                                       InitDataStoreHash ();
+                               LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
+
+                               if(slot!=null) {
+                                       datastorehash.Remove(slot);
+                               }
+                       }
                }
 
                public static object GetData(LocalDataStoreSlot slot) {
-                       // FIXME
-                       return(null);
+                       Hashtable slothash=GetTLSSlotHash();
+                       return(slothash[slot]);
                }
 
                public static AppDomain GetDomain() {
-                       // FIXME
-                       return(null);
+                       return AppDomain.CurrentDomain;
                }
 
-               public static int GetDomainID() {
-                       // FIXME
-                       return(0);
-               }
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern static int GetDomainID();
 
                public static LocalDataStoreSlot GetNamedDataSlot(string name) {
-                       // FIXME
-                       return(null);
+                       lock (datastore_lock) {
+                               if (datastorehash == null)
+                                       InitDataStoreHash ();
+                               LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
+
+                               if(slot==null) {
+                                       slot=AllocateNamedDataSlot(name);
+                               }
+                       
+                               return(slot);
+                       }
                }
+               
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern static void ResetAbort_internal();
 
-               public static void ResetAbort() {
-                       // FIXME
+               public static void ResetAbort()
+               {
+                       ResetAbort_internal();
                }
+               
+
+               public static void SetData(LocalDataStoreSlot slot,
+                                          object data) {
+                       Hashtable slothash=GetTLSSlotHash();
 
-               public static void SetData(LocalDataStoreSlot slot, object data) {
-                       // FIXME
+                       if(slothash.Contains(slot)) {
+                               slothash.Remove(slot);
+                       }
+                       
+                       slothash.Add(slot, data);
                }
 
-               // Returns milliseconds remaining (due to interrupted sleep)
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static int Sleep_internal(int ms);
+               private extern static void Sleep_internal(int ms);
 
-               // Causes thread to give up its timeslice
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Schedule_internal();
-               
                public static void Sleep(int millisecondsTimeout) {
-                       if(millisecondsTimeout<0) {
+                       if((millisecondsTimeout<0) && (millisecondsTimeout != Timeout.Infinite)) {
                                throw new ArgumentException("Negative timeout");
                        }
-                       if(millisecondsTimeout==0) {
-                               // Schedule another thread
-                               Schedule_internal();
-                       } else {
-                               Thread thread=CurrentThread;
-                               
-                               thread.state |= ThreadState.WaitSleepJoin;
-                               int ms_remaining=Sleep_internal(millisecondsTimeout);
-                               thread.state &= ~ThreadState.WaitSleepJoin;
-
-                               if(ms_remaining>0) {
-                                       throw new ThreadInterruptedException("Thread interrupted while sleeping");
-                               }
-                       }
-                       
+                       Thread thread=CurrentThread;
+                       Sleep_internal(millisecondsTimeout);
                }
 
                public static void Sleep(TimeSpan timeout) {
                        // LAMESPEC: says to throw ArgumentException too
-                       if(timeout.Milliseconds < 0 || timeout.Milliseconds > Int32.MaxValue) {
+                       int ms=Convert.ToInt32(timeout.TotalMilliseconds);
+                       
+                       if(ms < 0 || ms > Int32.MaxValue) {
                                throw new ArgumentOutOfRangeException("Timeout out of range");
                        }
-                       if(timeout.Milliseconds==0) {
-                               // Schedule another thread
-                               Schedule_internal();
-                       } else {
-                               Thread thread=CurrentThread;
-                               
-                               thread.state |= ThreadState.WaitSleepJoin;
-                               int ms_remaining=Sleep_internal(timeout.Milliseconds);
-                               thread.state &= ~ThreadState.WaitSleepJoin;
-                               
-                               if(ms_remaining>0) {
-                                       throw new ThreadInterruptedException("Thread interrupted while sleeping");
-                               }
-                       }
+
+                       Thread thread=CurrentThread;
+                       Sleep_internal(ms);
                }
 
-               private ThreadStart start_delegate=null;
-               
+               // Returns the system thread handle
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern IntPtr Thread_internal(ThreadStart start);
+
                public Thread(ThreadStart start) {
                        if(start==null) {
                                throw new ArgumentNullException("Null ThreadStart");
                        }
-
-                       // Nothing actually happens here, the fun
-                       // begins when Thread.Start() is called.  For
-                       // now, just record what the ThreadStart
-                       // delegate is.
-                       start_delegate=start;
+                       threadstart=start;
                }
 
+               [MonoTODO]
                public ApartmentState ApartmentState {
                        get {
-                               // FIXME
                                return(ApartmentState.Unknown);
                        }
                        
@@ -163,63 +288,145 @@ namespace System.Threading
                        }
                }
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private static extern int current_lcid ();
+
+               /* If the current_lcid() isn't known by CultureInfo,
+                * it will throw an exception which may cause
+                * String.Concat to try and recursively look up the
+                * CurrentCulture, which will throw an exception, etc.
+                * Use a boolean to short-circuit this scenario.
+                */
+               private static bool in_currentculture=false;
+               
                public CultureInfo CurrentCulture {
                        get {
-                               // FIXME
-                               return(null);
+                               if (current_culture == null) {
+                                       lock (typeof (Thread)) {
+                                               if(current_culture==null) {
+                                                       if(in_currentculture==true) {
+                                                               /* Bail out */
+                                                               current_culture = CultureInfo.InvariantCulture;
+                                                       } else {
+                                                               in_currentculture=true;
+                                                       
+                                                               current_culture = CultureInfo.ConstructCurrentCulture ();
+                                                       }
+                                               }
+                                               
+                                               in_currentculture=false;
+                                       }
+                               }
+                               
+                               return(current_culture);
                        }
                        
                        set {
+                               current_culture = value;
                        }
                }
 
                public CultureInfo CurrentUICulture {
                        get {
-                               // FIXME
-                               return(null);
+                               if (current_ui_culture == null) {
+                                       lock (synch_lock) {
+                                               if(current_ui_culture==null) {
+                                                       /* We don't
+                                                        * distinguish
+                                                        * between
+                                                        * System and
+                                                        * UI cultures
+                                                        */
+                                                       current_ui_culture = CultureInfo.ConstructCurrentUICulture ();
+                                               }
+                                       }
+                               }
+                               
+                               return(current_ui_culture);
                        }
                        
                        set {
+                               current_ui_culture = value;
+                       }
+               }
+
+               public bool IsThreadPoolThread {
+                       get {
+                               return IsThreadPoolThreadInternal;
+                       }
+               }
+
+               internal bool IsThreadPoolThreadInternal {
+                       get {
+                               return threadpool_thread;
+                       }
+                       set {
+                               threadpool_thread = value;
                        }
                }
 
                public bool IsAlive {
                        get {
-                               // LAMESPEC: is a Stopped thread dead?
-                               if((state & ThreadState.Running) != 0 ||
-                                  (state & ThreadState.Stopped) != 0) {
-                                       return(true);
-                               } else {
+                               ThreadState curstate=state;
+                               
+                               if((curstate & ThreadState.Aborted) != 0 ||
+                                  (curstate & ThreadState.Stopped) != 0 ||
+                                  (curstate & ThreadState.Unstarted) != 0) {
                                        return(false);
+                               } else {
+                                       return(true);
                                }
                        }
                }
 
                public bool IsBackground {
                        get {
-                               // FIXME
-                               return(false);
+                               if((state & ThreadState.Background) != 0) {
+                                       return(true);
+                               } else {
+                                       return(false);
+                               }
                        }
                        
                        set {
+                               if(value==true) {
+                                       set_state(ThreadState.Background);
+                               } else {
+                                       clr_state(ThreadState.Background);
+                               }
                        }
                }
 
-               private string thread_name=null;
-               
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern string GetName_internal ();
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern void SetName_internal (String name);
+
+               /* 
+                * The thread name must be shared by appdomains, so it is stored in
+                * unmanaged code.
+                */
+
                public string Name {
                        get {
-                               return(thread_name);
+                               return GetName_internal ();
                        }
                        
                        set {
-                               thread_name=value;
+                               lock (synch_lock) {
+                                       if(Name!=null) {
+                                               throw new InvalidOperationException ("Thread.Name can only be set once.");
+                                       }
+                               
+                                       SetName_internal (value);
+                               }
                        }
                }
 
+               [MonoTODO]
                public ThreadPriority Priority {
                        get {
-                               // FIXME
                                return(ThreadPriority.Lowest);
                        }
                        
@@ -227,111 +434,249 @@ namespace System.Threading
                        }
                }
 
-               private ThreadState state=ThreadState.Unstarted;
-               
                public ThreadState ThreadState {
                        get {
                                return(state);
                        }
                }
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern void Abort_internal (object stateInfo);
+
                public void Abort() {
-                       // FIXME
+                       Abort_internal (null);
                }
 
                public void Abort(object stateInfo) {
-                       // FIXME
+                       Abort_internal(stateInfo);
                }
+               
 
+               [MonoTODO]
                public void Interrupt() {
-                       // FIXME
                }
 
                // The current thread joins with 'this'. Set ms to 0 to block
                // until this actually exits.
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern /*bool*/ int Join_internal(int ms, UInt32 handle);
+               private extern bool Join_internal(int ms, IntPtr handle);
                
                public void Join() {
-                       if(state == ThreadState.Unstarted) {
+                       if((state & ThreadState.Unstarted) != 0) {
                                throw new ThreadStateException("Thread has not been started");
                        }
                        
                        Thread thread=CurrentThread;
                                
-                       thread.state |= ThreadState.WaitSleepJoin;
-                       Join_internal(0, system_thread_handle);
-                       thread.state &= ~ThreadState.WaitSleepJoin;
+                       Join_internal(Timeout.Infinite, system_thread_handle);
                }
 
                public bool Join(int millisecondsTimeout) {
-                       if(millisecondsTimeout<0) {
-                               throw new ArgumentException("Timeout less than zero");
-                       }
-                       if(state == ThreadState.Unstarted) {
+                       if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout < 0)
+                               throw new ArgumentException ("Timeout less than zero", "millisecondsTimeout");
+
+                       if((state & ThreadState.Unstarted) != 0) {
                                throw new ThreadStateException("Thread has not been started");
                        }
 
                        Thread thread=CurrentThread;
-                               
-                       thread.state |= ThreadState.WaitSleepJoin;
-                       bool ret=(Join_internal(millisecondsTimeout,
-                                               system_thread_handle)==1);
-                       thread.state &= ~ThreadState.WaitSleepJoin;
-
-                       return(ret);
+                       return Join_internal(millisecondsTimeout, system_thread_handle);
                }
 
                public bool Join(TimeSpan timeout) {
                        // LAMESPEC: says to throw ArgumentException too
-                       if(timeout.Milliseconds < 0 || timeout.Milliseconds > Int32.MaxValue) {
+                       int ms=Convert.ToInt32(timeout.TotalMilliseconds);
+                       
+                       if(ms < 0 || ms > Int32.MaxValue) {
                                throw new ArgumentOutOfRangeException("timeout out of range");
                        }
-                       if(state == ThreadState.Unstarted) {
+                       if((state & ThreadState.Unstarted) != 0) {
                                throw new ThreadStateException("Thread has not been started");
                        }
 
                        Thread thread=CurrentThread;
-                               
-                       thread.state |= ThreadState.WaitSleepJoin;
-                       bool ret=(Join_internal(timeout.Milliseconds,
-                                               system_thread_handle)==1);
-                       thread.state &= ~ThreadState.WaitSleepJoin;
+                       return Join_internal(ms, system_thread_handle);
+               }
 
-                       return(ret);
+#if NET_1_1
+               [MonoTODO ("seems required for multi-processors systems like Itanium")]
+               public static void MemoryBarrier ()
+               {
+                       throw new NotImplementedException ();
+               }
+#endif
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern void Resume_internal();
+
+               public void Resume () 
+               {
+                       if ((state & ThreadState.Unstarted) != 0 || !IsAlive || 
+                               ((state & ThreadState.Suspended) == 0 && (state & ThreadState.SuspendRequested) == 0)) 
+                       {
+                               throw new ThreadStateException("Thread has not been started, or is dead");
+                       }
+                       
+                       Resume_internal ();
                }
 
-               public void Resume() {
-                       // FIXME
+               [MonoTODO]
+               public static void SpinWait (int iterations) 
+               {
+                       throw new NotImplementedException ();
                }
-               
-               // stores a pthread_t, which is defined as unsigned long
-               // on my system.  I _think_ windows uses "unsigned int" for
-               // its thread handles, so that _should_ work too.
-               private UInt32 system_thread_handle;
 
-               // Returns the system thread handle
+               // Launches the thread
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern UInt32 Start_internal(ThreadStart start);
+               private extern void Start_internal(IntPtr handle);
                
                public void Start() {
-                       if(state!=ThreadState.Unstarted) {
-                               throw new ThreadStateException("Thread has already been started");
-                       }
+                       lock(synch_lock) {
+                               if((state & ThreadState.Unstarted) == 0) {
+                                       throw new ThreadStateException("Thread has already been started");
+                               }
+                               
 
-                       state=ThreadState.Running;
-                       
-                       // Don't rely on system_thread_handle being
-                       // set before start_delegate runs!
-                       system_thread_handle=Start_internal(start_delegate);
+                               // Thread_internal creates the new thread, but
+                               // blocks it until Start() is called later.
+                               system_thread_handle=Thread_internal(threadstart);
+
+                               if (system_thread_handle == (IntPtr) 0) {
+                                       throw new SystemException ("Thread creation failed");
+                               }
+
+                               // Launch this thread
+                               Start_internal(system_thread_handle);
+
+                               // Mark the thread state as Running
+                               // (which is all bits
+                               // cleared). Therefore just remove the
+                               // Unstarted bit
+                               clr_state(ThreadState.Unstarted);
+                       }
                }
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern void Suspend_internal();
+
                public void Suspend() {
-                       // FIXME
+                       if((state & ThreadState.Unstarted) != 0 || !IsAlive) {
+                               throw new ThreadStateException("Thread has not been started, or is dead");
+                       }
+                       Suspend_internal ();
                }
 
+               // Closes the system thread handle
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern void Thread_free_internal(IntPtr handle);
+
                ~Thread() {
-                       // FIXME
+                       // Free up the handle
+                       if (system_thread_handle != (IntPtr) 0)
+                               Thread_free_internal(system_thread_handle);
+               }
+
+               private void set_state(ThreadState set) {
+                       lock(synch_lock) {
+                               state |= set;
+                       }
+               }
+               private void clr_state(ThreadState clr) {
+                       lock(synch_lock) {
+                               state &= ~clr;
+                       }
                }
+
+#if NET_1_1
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static byte VolatileRead (ref byte address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static double VolatileRead (ref double address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static short VolatileRead (ref short address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static int VolatileRead (ref int address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static long VolatileRead (ref long address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static IntPtr VolatileRead (ref IntPtr address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static object VolatileRead (ref object address);
+
+               [CLSCompliant(false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static sbyte VolatileRead (ref sbyte address);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static float VolatileRead (ref float address);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static ushort VolatileRead (ref ushort address);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static uint VolatileRead (ref uint address);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static ulong VolatileRead (ref ulong address);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static UIntPtr VolatileRead (ref UIntPtr address);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref byte address, byte value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref double address, double value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref short address, short value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref int address, int value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref long address, long value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref IntPtr address, IntPtr value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref object address, object value);
+
+               [CLSCompliant(false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref sbyte address, sbyte value);
+               
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref float address, float value);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref ushort address, ushort value);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref uint address, uint value);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref ulong address, ulong value);
+
+               [CLSCompliant (false)]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern public static void VolatileWrite (ref UIntPtr address, UIntPtr value);
+               
+#endif
+               
        }
 }