Aquire Singleton class Instance Multithread

Para obtener la instancia de la clase con el patrón de Singleton, quiero usar la siguiente función:

Esto es un boceto

interface

uses SyncObjs;

type
  TMCriticalSection = class(TCriticalSection)
  private
    Dummy : array [0..95] of Byte;
  end;

var
  InstanceNumber : Integer;
  AObject: TObject;
  CriticalSection: TMCriticalSection;

function getInstance: TObject;

implementation

uses Windows;

function getInstance: TObject;
begin
   //I Want somehow use InterlockedCompareExchange instead of CriticalSession, for example

   if InterlockedCompareExchange(InstanceNumber, 1, 0) > 0 then
   begin
     Result := AObject;
   end
   else
   begin
      CriticalSection.Enter;
      try
        AObject := TObject.Create;
      finally
        CriticalSection.Leave;
      end;
      InterlockedIncrement(InstanceNumber);
      Result := AObject
   end;
end;

initialization
  CriticalSection := TMCriticalSection.Create;
  InstanceNumber := 0;

finalization;
  CriticalSection.Free;

end.

Tres preguntas:

1- ¿Es seguro este hilo de diseño? Especialmente la parte con InterlockedExchange.
2- ¿Cómo usar el InterlockedCompareExchange? ¿Es posible hacer lo que estoy tratando?
3- ¿Es este diseño mejor que involucrar todo el código dentro del alcance de la sección crítica?

Nota: mi objeto es seguro para subprocesos, solo la construcción que necesito para serializar.
Este no es el código de intire, solo la parte importante, es decir, la función getInstance.

Editar

I NECESITAR para utilizar algún tipo de objeto singleton.
¿Hay alguna forma de usar InterlockedCompareExchange para comparar si el valor de Número de instancia es cero?
Y
1 - Crea el objeto solo cuando es 0, de lo contrario, devuelve la instancia.
2 - Cuando el valor es 0: Ingrese en la sección crítica. Crea el objeto. Deja la sección crítica.
3 - ¿Sería mejor hacerlo de esta manera, en lugar de involucrar a todo el código dentro del alcance de la sección crítica?

Respuestas a la pregunta(2)

Su respuesta a la pregunta