I am comparing performance of many processes each trying to acquire a semaphore (the semaphore is always in contention) on an ARM8 server with a Linux ubuntu 4.15.0-112
First I used a named posix semaphore and then a system v semaphore where the semaphore set had 1 semaphore.
The performance was 8% worse with the system v semaphore. I know it has worse performance when there is no contention on the semaphore, but I don't understand the performance hit when there is. When running the same on intel I don't see any difference in performance, but I believe something else is the bottleneck when running on intel.
I want to use System V Semaphore for two reasons, release semaphore in case one of the processes crashed and can increment/decrement by any value instead of +-1
This is the code I wrote for the system v semaphore (initialize is called only from 1 process and I get the same performance hit without the undo flag in wait and post)
void init_semaphore(bool initialize, int initCount, int& semId)
{
key_t key;
char* file_path = "/tmp/semv";
char proj_id ='p';
if (initialize)
{
key = ftok(file_path, proj_id);
if (key == -1) {
perror("ftok");
exit(EXIT_FAILURE);
}
int flags = IPC_CREAT | 0666;
semId = semget(key, 1, flags);
if (semId == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
i = semctl(semId, 0, SETVAL, initCount);
if (i == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
i = semctl(semId, 0, GETVAL);
printf("current value of %d is %d\n", semId, i);
}
else
{
key = ftok(file_path, proj_id);
if (key == -1) {
perror("ftok");
exit(EXIT_FAILURE);
}
semId = semget(key, 1, 0);
if (semId == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
}
}
void release_semaphore(int semId)
{
int i = semctl(semId, 0, IPC_RMID);
if (i == -1) {
perror("semctl: semctl failed");
exit(1);
}
}
void post(int semId)
{
sembuf sops_post[1];
sops_post[0].sem_num = 0;
sops_post[0].sem_op = 1;
sops_post[0].sem_flg = SEM_UNDO;
semop(semId, sops_post, 1);
}
void wait(int semId)
{
sembuf sops_wait[1];
sops_wait[0].sem_num = 0;
sops_wait[0].sem_op = -1;
sops_wait[0].sem_flg = SEM_UNDO;
semop(semId, sops_wait, 1);
}