mcst-linux-kernel/glibc-2.35/nptl/tst-bug-64685.c

109 lines
1.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#ifndef SEM_R
#define SEM_R 0400
#endif
#ifndef SEM_A
#define SEM_A 0200
#endif
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void init_smph(int *sm)
{
// Get a semaphore set with one semaphore.
sm[0] = semget(IPC_PRIVATE, 1, SEM_R | SEM_A);
if (sm[0] == -1) {
fprintf(stderr, "could not obtain semaphore set\n");
exit(-1);
}
// Initialize the semaphore.
union semun val;
val.val = 0;
if (semctl(sm[0], 0, SETVAL, val) == -1) {
fprintf(stderr, "could not initialize semaphore\n");
exit(-1);
}
}
void destroy_smph(int *sm)
{
union semun val;
val.val = 0; // Avoid uninitialized variable warning.
semctl(sm[0], 0, IPC_RMID, val);
}
void post_smph(int *sm)
{
struct sembuf op[1];
op->sem_num = 0;
op->sem_op = 1;
op->sem_flg = 0;
if (semop(sm[0], op, 1) == -1) {
fprintf(stderr, "could not signal semaphore");
exit(-1);
}
}
void wait_smph(int *sm)
{
struct sembuf op[1];
op->sem_num = 0;
op->sem_op = -1;
op->sem_flg = 0;
if (semop(sm[0], op, 1) == -1) {
fprintf(stderr, "could not wait for semaphore");
exit(-1);
}
}
int sem;
int global;
void *right(void *args)
{
wait_smph(&sem);
global = 0;
return args;
}
void *left(void *args)
{
int i;
for (i = 1; i < 400000; ++i) {
global = i;
}
post_smph(&sem);
return args;
}
int
main (void)
{
init_smph(&sem);
pthread_t thr1, thr2;
pthread_create(&thr1, NULL, right, NULL);
pthread_create(&thr2, NULL, left, NULL);
pthread_join(thr1, NULL);
pthread_join(thr2, NULL);
destroy_smph(&sem);
//printf("%d\n", global);
assert(global == 0);
return 0;
}