PureBasic

Forums PureBasic
Nous sommes le Mer 19/Juin/2019 5:55

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 12 messages ] 
Auteur Message
 Sujet du message: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Sam 09/Jan/2016 21:07 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Bonjour, pour les besoins des objects COM, il faut utiliser une fonction qui est InterlockedIncrement, cette fonction n'existe pas pour les OS x64, il faut la créer en assembleur, voici comment elle est définie, est t'il possible de le convertir pour purebasic?

Code:
#if !defined(_M_X64)
// When compiling for windows 32bit, the 8byte interlocked operations are not provided by microsoft
// (because they need at least i586 so its not generic enough.. ... )
forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 _cmp){
   _asm{
      lea esi,_cmp;
      lea edi,exch;
       
      mov eax,[esi];
      mov edx,4[esi];
      mov ebx,[edi];
      mov ecx,4[edi];
      mov esi,dest;
      
      lock CMPXCHG8B [esi];               
   }
}


forceinline volatile int64 InterlockedIncrement64(volatile int64 *addend){
   __int64 old;
   do{
      old = *addend;
   }while(InterlockedCompareExchange64(addend, (old+1), old) != old);

   return (old + 1);
}



forceinline volatile int64 InterlockedDecrement64(volatile int64 *addend){
   __int64 old;

   do{
      old = *addend;
   }while(InterlockedCompareExchange64(addend, (old-1), old) != old);

   return (old - 1);
}


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Sam 09/Jan/2016 23:29 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
j'ai fait ça, est-ce que c'est bon?

Code:
Procedure.i InterlockedCompareExchange64(*deste, exch.i, COMPare.i)
      !LEA r8, [p.v_COMPare]
      !LEA r9,[p.v_exch]
       
      !MOV rax,[r8]
      !MOV rcx,[r9]
      !MOV rdx,[p.p_deste]
      
      !LOCK CMPXCHG8B [rdx]      
EndProcedure
   
Procedure.i InterlockedIncrement64(*addend.integer)
  Protected old.integer
 
   Repeat
      old\i = *addend\i
   Until (InterlockedCompareExchange64(*addend, (old\i+1), old\i) <> old\i)

   ProcedureReturn (old\i + 1)
EndProcedure

Procedure.i InterlockedDecrement64(*addend.integer)
  Protected old.integer
 
   Repeat
      old\i = *addend\i
   Until (InterlockedCompareExchange64(*addend, (old\i+1), old\i) <> old\i)

   ProcedureReturn (old\i - 1)
EndProcedure


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 0:37 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8670
Je voudrai bien t'aider mais c'est au delà de mes compétences..

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 11:27 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
L'exemple est pour du 32 bit, il n'y a pas beaucoup d'instruction, je ne pense pas que ce soit compliqué à faire d'une façon ou d'une autre pour du 64 bit.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 11:54 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 22/Jan/2004 14:31
Messages: 3521
Localisation: Sourans
Salut Nico,

je ne suis pas un gourou en C.

Ce que je pense avoir compris :

#if !defined(_M_X64)

veut dire que les procedures seront utilisées si le processeur _M_X64 n'est pas défini (< i586 ?)

Pour ce que je comprend, je pense qu'il faut laisser les registres 32 bits en asm.
Utiliser un compiler if qui génère le code à la compilation ou alors détecter le processeur et générer 2 procedures car les procedures en 64 bits existent.

InterlockedCompareExchange64
https://msdn.microsoft.com/fr-fr/librar ... 85%29.aspx

InterlockedIncrement64
https://msdn.microsoft.com/fr-fr/librar ... 85%29.aspx

Les utiliser en API si _M_X64 existe sinon le code asm (les 3 procedures)

CMPXCHG8B compare le contenu de EAX/EDX avec la mémoire 64 bit pointée par esi et echange le contenu si égal
si c'est égal, le drapeau ZF passe à 1, ECX/EBX est chargé et mis dans la mémoire pointée par esi.
Le drapeau ZF passe à 0 et le contenu de la mémoire 64 bit est chargé dans EDX/EAX


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 12:24 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Salut Denis, sur le Forum En, Mistrel a sorti les procédure asm équivalente, je viens juste de le trouver, ici:
http://www.purebasic.fr/english/viewtopic.php?f=12&t=38024&hilit=cmpxchg

Cela te paraît correct, pas au niveau résultat car il est bon mais au niveau du code?
Est ce qu'il peut y avoir un conflit avec des threads pour les registres.
Dans les exemples que j'ai trouvé, il y avait un Do-While?

Code:
Procedure InterlockedExchange(*Destination.Integer, Value.i)
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x86
    !mov ecx,[p.p_Destination]
    !mov eax,[p.v_Value]
    !xchg [ecx],eax
  CompilerEndIf
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
    !mov rcx,[p.p_Destination]
    !mov rax,[p.v_Value]
    !xchg [rcx],rax
  CompilerEndIf
  ProcedureReturn
EndProcedure

Procedure InterlockedCompareExchange(*Destination.Integer, Exchange.i, Comparand.i)
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x86
    !mov ecx,[p.p_Destination]
    !mov eax,[p.v_Comparand]
    !mov edx,[p.v_Exchange]
    !lock cmpxchg [ecx],edx
  CompilerEndIf
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
    !mov rcx,[p.p_Destination]
    !mov rax,[p.v_Comparand]
    !mov rdx,[p.v_Exchange]
    !lock cmpxchg [rcx],rdx
  CompilerEndIf
  ProcedureReturn
EndProcedure


InterlockedExchange(@This,2)
Debug This

InterlockedCompareExchange(@This,4,1)
Debug This
InterlockedCompareExchange(@This,4,2)
Debug This


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 18:50 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 22/Jan/2004 14:31
Messages: 3521
Localisation: Sourans
Nico,

je ne pense pas que le code de Mistrel corresponde à l'exemple en C/asm de la procedure.

forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 _cmp) passe
des arguments en 64 bit sous compilation 32 alors que le code de Mistrel les passe en 32 bits

_M_X64 semblerais indiquer la plateforme 64 bit (sous réserve)
http://blogs.msdn.com/b/reiley/archive/ ... sited.aspx

Je pense qu'il faut donc modifier les arguments de la procédure pour passer du 64 bit en argument.

Des gourous en C ici pour confirmer ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 19:06 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Je vois ce que tu veux dire mais sur le site MSDN, il y a bien plusieurs fonctions, dont une qui opère sur des variables 32 bit et une autre sur les variables 64 bit, donc je dirais que c'est bon; l'exemple que j'ai mis est peut être pour autre chose, voir ici:
https://msdn.microsoft.com/fr-fr/library/2ddez55b.aspx


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Dim 10/Jan/2016 19:50 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Finalement, je vais utiliser InterlockedCompareExchange et faire un repeat until comme dans l'exemple, cela me paraît plus sécurisé.

Code:
Procedure InterlockedCompareExchange(*Destination.Integer, Exchange.i, Comparand.i)
  EnableASM
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x86
    !mov ecx,[p.p_Destination]
    !mov eax,[p.v_Comparand]
    !mov edx,[p.v_Exchange]
    !lock cmpxchg [ecx],edx
  CompilerEndIf
  CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
    !mov rcx,[p.p_Destination]
    !mov rax,[p.v_Comparand]
    !mov rdx,[p.v_Exchange]
    !lock cmpxchg [rcx],rdx
  CompilerEndIf
  ProcedureReturn
  DisableASM
EndProcedure

Procedure.i AudioEndpointVolumeCallback_AddRef(*pObject.AudioEndpointVolumeCallback)
  Protected Ref.i
 
  Debug "AudioEndpointVolumeCallback_AddRef"
 
  Repeat
    Ref = *pObject\Refcount
    Until InterlockedCompareExchange(@*pObject\Refcount, Ref + 1, Ref) <> *pObject\Refcount
  Debug "*pObject\Refcount = " + Str(*pObject\Refcount)
 
  ProcedureReturn Ref + 1
EndProcedure

Procedure.i AudioEndpointVolumeCallback_Release(*pObject.AudioEndpointVolumeCallback)
  Protected Ref.i
 
  Debug "AudioEndpointVolumeCallback_Release"
 
  Repeat
    Ref = *pObject\Refcount
  Until InterlockedCompareExchange(@*pObject\Refcount, Ref - 1, Ref) <> *pObject\Refcount
 
  Debug "*pObject\Refcount = " + Str(*pObject\Refcount)
 
  If Ref -1 = 0
    AudioEndpointVolumeCallback\pAudioEndpointVolumeCallback = 0
    Debug "delete element --------------------------------"
    *pObject = 0
  EndIf
 
  ProcedureReturn Ref - 1
EndProcedure


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Lun 11/Jan/2016 14:47 
Hors ligne

Inscription: Mer 04/Nov/2015 17:39
Messages: 991
Et bien, ça vole haut :?
A quoi ça sert en gros ?

_________________
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Lun 11/Jan/2016 19:14 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Cette ligne là, !lock cmpxchg [rcx],rdx, compare le contenu de *Destination et Comparand et si c'est la même valeur, il met la valeur de Exchange dans Destination sinon l'opération n'est pas effectuée.

Dans un contexte Multithread, il faut s'assurer qu'un seul thread puisse modifier une valeur; par exemple dans un contexte d'interface com, il y a une fonction qui incrémente une valeur et l'autre qui l'a décrémente, les valeurs peuvent être fausses si les threads accèdent en même temps sur la variable.

L'élément Lock bloque l'exécution qui suit pour le thread qui l'exécute, donc un seul thread y a accès à la fois, c'est bien sauf qu'au moment de la lecture et au moment de l'écriture, il se passe un peu de temps. Lors de l'appel de la fonction InterlockedCompareExchange, *Destination et Comparand ont la même valeur, donc normalement l'opération se déroule avec succès, si il y a un problème (on lit la valeur, pendant ce temps un autre thread vient juste de l'incrémenter ce qui fait que la valeur contenu dans le pointeur *Destination a changé aussi, donc l'appel à InterlockedCompareExchange échoue, donc on refait un appel de cette fonction grâce au repeat until.

Bon je ne sais pas si c'est très clair, mais voilà.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Besoin d'aide pour InterlockedIncrement64 en ASM
MessagePosté: Lun 11/Jan/2016 23:35 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 13/Fév/2004 0:57
Messages: 3702
Je viens de faire des tests avec des threads (pour vérifier le bon fonctionnement de ce code asm) et cela fonctionne rarement avec le debugger activé et rate quelque fois sans le debugger.

Je vais remettre un Mutex.


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 12 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye