Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[linux] pthread_mutex_destroy

3 réponses
Avatar
JKB
Bonjour à tous,

Avant de faire un rapport de bug, je vous soumets une bizarrerie
observée ce soir avec la glibc. J'aimerais savoir s'il provient d'une
erreur dans mon code ou s'il s'agit d'un bug.

Mon code :

if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0)
{
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

if ((*s_etat_processus).taille_pile_objets <= (10 * ((*s_etat_processus)
.estimation_taille_tampon + 1)))
{
(*s_objet).objet = (*s_etat_processus).pile_objets;
(*s_etat_processus).pile_objets = s_objet;
(*s_etat_processus).taille_pile_objets++;
}
else
{
if (i=pthread_mutex_destroy(&((*s_objet).mutex)) != 0)
{
printf(">> %d %d\n", i, EBUSY);
perror("mutex_destroy");
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

free(s_objet);
}

Ça correspond à la fin d'un allocateur multithreadé. Le mutex est
bien initialisé. le pthread_mutex_unlock ne provoque aucune erreur. Par
contre, le programme plante sur le pthread_mutex_destroy (enfin, il lève
une erreur d_es_processus qui provoque chez moi un arrêt).

La valeur renvoyée par pthread_mutex_destroy est 1 (!). Or dans la
doc, je vois écrit en toute lettre que la seule erreur possible est
EBUSY (soit 16 chez moi). Première question, à quelle erreur correspond
donc ce code d'erreur ?

Sortie du programme :

>> 1 16
mutex_destroy: Success

Si le mutex n'était pas initialisé correctement, je pense que le
pthread_mutex_unlock (et le lock précédent) devraient planter. Si
j'enlève le if autour du pthread_mutex_destroy, mon programme fonctionne
parfaitement (avec ses mutexes). Une idée ? Parce que moi, je sèche.
Je précise qu'au moment où ça plante, je n'ai encore aucun thread
concurrent.

Cordialement,

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.

3 réponses

Avatar
JKB
Le 04-02-2009, ? propos de
[linux] pthread_mutex_destroy,
JKB ?crivait dans fr.comp.os.unix :
Bonjour à tous,

Avant de faire un rapport de bug, je vous soumets une bizarrerie
observée ce soir avec la glibc. J'aimerais savoir s'il provient d'une
erreur dans mon code ou s'il s'agit d'un bug.

Mon code :

if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0)
{
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

if ((*s_etat_processus).taille_pile_objets <= (10 * ((*s_etat_processus)
.estimation_taille_tampon + 1)))
{
(*s_objet).objet = (*s_etat_processus).pile_objets;
(*s_etat_processus).pile_objets = s_objet;
(*s_etat_processus).taille_pile_objets++;
}
else
{



Boulette :
if (i=pthread_mutex_destroy(&((*s_objet).mutex)) != 0)



Lire:
if ((i=pthread_mutex_destroy(&((*s_objet).mutex))) != 0)
{
printf(">> %d %dn", i, EBUSY);
perror("mutex_destroy");
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

free(s_objet);
}




Mais c'est encore pire, ça renvoit EBUSY !

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Avatar
talon
JKB wrote:

Lire:
> if ((i=pthread_mutex_destroy(&((*s_objet).mutex))) != 0)
> {
> printf(">> %d %dn", i, EBUSY);
> perror("mutex_destroy");
> (*s_etat_processus).erreur_systeme = d_es_processus;
> return;
> }
>
> free(s_objet);
> }
>

Mais c'est encore pire, ça renvoit EBUSY !



Butenhof dit:

You can destroy a mutex as soon as you are sure no threads are
blocked on the mutex.

EBUSY correspond à ce cas, donc est-tu bien sur?


JKB




--

Michel TALON
Avatar
JKB
Le 04-02-2009, ? propos de
Re: [linux] pthread_mutex_destroy,
JKB ?crivait dans fr.comp.os.unix :

Bonsoir,

Je continue mes recherches et j'avoue que je comprends de moins en
moins. J'ai modifié mon code pour cracher le contenu de la structure
pthread_mutex_t :

(struct_objet est une structure de données complexe qui contient un
mutex pour en protéger l'accès)

if (pthread_mutex_lock(&((*s_objet).mutex)) != 0)
{
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

< section de code critique >

printf("> %d %d %d %u %ld %sn", s_objet->mutex.__data.__lock,
s_objet->mutex.__data.__count,
s_objet->mutex.__data.__owner,
s_objet->mutex.__data.__nusers,
s_objet->mutex.__align,
s_objet->mutex.__size);
if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0)
{
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}
printf("< %d %d %d %u %ld %sn", s_objet->mutex.__data.__lock,
s_objet->mutex.__data.__count,
s_objet->mutex.__data.__owner,
s_objet->mutex.__data.__nusers,
s_objet->mutex.__align,
s_objet->mutex.__size);

if ((*s_etat_processus).taille_pile_objets <= (10 * ((*s_etat_processus)
.estimation_taille_tampon + 1)))
{
(*s_objet).objet = (*s_etat_processus).pile_objets;
(*s_etat_processus).pile_objets = s_objet;
(*s_etat_processus).taille_pile_objets++;
}
else
{
printf("<2 %d %d %d %u %ld %sn", s_objet->mutex.__data.__lock,
s_objet->mutex.__data.__count,
s_objet->mutex.__data.__owner,
s_objet->mutex.__data.__nusers,
s_objet->mutex.__align,
s_objet->mutex.__size);
if ((i=pthread_mutex_destroy(&((*s_objet).mutex))) != 0)
{
printf("<3 %d %d %d %u %ld %sn", s_objet->mutex.__data.__lock,
s_objet->mutex.__data.__count,
s_objet->mutex.__data.__owner,
s_objet->mutex.__data.__nusers,
s_objet->mutex.__align,
s_objet->mutex.__size);
printf(">> %d %dn", i, EBUSY);
(*s_etat_processus).erreur_systeme = d_es_processus;
return;
}

free(s_objet);
}

À l'exécution, j'obiens :

1 0 6337 1 1


< 0 0 0 0 0 <-- mutex effectivement libéré
<2 0 0 0 0 0
1 0 6337 1 1


< 0 0 0 0 0
<2 0 0 0 0 0
... <-- ça fonctionne bien durant un certain temps
1 0 6337 0 1 <-- le unlock se passe bien (sinon, on ne continuerait


pas !)
< 0 0 0 4294967295 0 <-- mutex effectivement libéré, mais pourquoi la
valeur __align a-t-elle changée ? Et que
veut-elle dire ?
<2 0 0 0 4294967295 0
<3 0 0 0 4294967295 0
16 16





Je comprendrais encore que j'écrase le mutex par une écriture
foireuse en mémoire, mais je n'ai pas l'impression que ce soit le cas.
J'ai essayé de faire passer la moulinette dans valgrind et efence sans
que quelque chose ne me saute aux yeux. Par ailleurs, c'est
_strictement_ reproductible (et toujours au même endroit). Cela foire
même avec un seul thread. Est-ce que quelqu'un a déjà vu un tel truc ?

Cordialement,

JKB

PS: Xpost + Fu2

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.