forked from LLNL/libmsr
/
highlander.c
110 lines (100 loc) · 2.9 KB
/
highlander.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
*
* Produced at the Lawrence Livermore National Laboratory. Written by:
* Barry Rountree <rountree@llnl.gov>,
* Daniel Ellsworth <ellsworth8@llnl.gov>,
* Scott Walker <walker91@llnl.gov>, and
* Kathleen Shoga <shoga1@llnl.gov>.
*
* LLNL-CODE-645430
*
* All rights reserved.
*
* This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git.
*
* Please also read libmsr/LICENSE for our notice and the LGPL.
*
* libmsr is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License (as published by the Free
* Software Foundation) version 2.1 dated February 1999.
*
* libmsr is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libmsr; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
/// Highlander... because there can be only one.
#include <fcntl.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
static int amHighlander = -1;
static sem_t *semk = NULL;
static sem_t *seml = NULL;
/// @brief Determines/initializes the process highlander status.
int highlander(void)
{
if (amHighlander != -1)
{
return amHighlander;
}
semk = sem_open("/power_wrapperK", O_CREAT | O_EXCL, 0600, 0);
if(semk == NULL || semk == SEM_FAILED)
{
semk = sem_open("/power_wrapperK", O_CREAT, 0600, 0);
seml = sem_open("/power_wrapperL", O_CREAT, 0600, 0);
sem_post(semk);
int v;
sem_getvalue(semk, &v);
amHighlander = 0;
return 0;
}
seml = sem_open("/power_wrapperL", O_CREAT, 0600, 0);
amHighlander = 1;
return 1;
}
int highlander_clean(void)
{
// remove the named semaphores
fprintf(stdout, "Removing named semaphore /power_wrapperK\n");
sem_unlink("/power_wrapperK");
fprintf(stdout, "Removing named semaphore /power_wrapperL\n");
sem_unlink("/power_wrapperL");
return 1;
}
/// @brief Causes the highlander to wait until all foes have called wait.
int highlander_wait(void)
{
if (amHighlander < 0)
{
return 1;
}
if (amHighlander)
{
int v;
sem_getvalue(semk, &v);
while (v > 1)
{
sem_wait(seml);
}
sem_close(semk);
sem_close(seml);
sem_unlink("/power_wrapperK");
sem_unlink("/power_wrapperL");
return 0;
}
else
{
sem_wait(semk);
sem_post(seml);
sem_close(semk);
sem_close(seml);
return 0;
}
return 1;
}