Coverage Report

Created: 2025-08-03 06:40

/src/strongswan/src/libstrongswan/threading/spinlock.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2012 Tobias Brunner
3
 *
4
 * Copyright (C) secunet Security Networks AG
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
#include <pthread.h>
18
19
#include <library.h>
20
#include <utils/debug.h>
21
22
#include "spinlock.h"
23
#include "mutex.h"
24
#include "lock_profiler.h"
25
26
typedef struct private_spinlock_t private_spinlock_t;
27
28
/**
29
 * private data
30
 */
31
struct private_spinlock_t {
32
33
  /**
34
   * public functions
35
   */
36
  spinlock_t public;
37
38
#ifdef HAVE_PTHREAD_SPIN_INIT
39
40
  /**
41
   * wrapped pthread spin lock
42
   */
43
  pthread_spinlock_t spinlock;
44
45
  /**
46
   * profiling info, if enabled (the mutex below does profile itself)
47
   */
48
  lock_profile_t profile;
49
50
#else /* HAVE_PTHREAD_SPIN_INIT */
51
52
  /**
53
   * use a mutex if spin locks are not available
54
   */
55
  mutex_t *mutex;
56
57
#endif /* HAVE_PTHREAD_SPIN_INIT */
58
};
59
60
METHOD(spinlock_t, lock, void,
61
  private_spinlock_t *this)
62
0
{
63
0
#ifdef HAVE_PTHREAD_SPIN_INIT
64
0
  int err;
65
66
0
  profiler_start(&this->profile);
67
0
  err = pthread_spin_lock(&this->spinlock);
68
0
  if (err)
69
0
  {
70
0
    DBG1(DBG_LIB, "!!! SPIN LOCK LOCK ERROR: %s !!!", strerror(err));
71
0
  }
72
0
  profiler_end(&this->profile);
73
#else
74
  this->mutex->lock(this->mutex);
75
#endif
76
0
}
77
78
METHOD(spinlock_t, unlock, void,
79
  private_spinlock_t *this)
80
0
{
81
0
#ifdef HAVE_PTHREAD_SPIN_INIT
82
0
  int err;
83
84
0
  err = pthread_spin_unlock(&this->spinlock);
85
0
  if (err)
86
0
  {
87
0
    DBG1(DBG_LIB, "!!! SPIN LOCK UNLOCK ERROR: %s !!!", strerror(err));
88
0
  }
89
#else
90
  this->mutex->unlock(this->mutex);
91
#endif
92
0
}
93
94
METHOD(spinlock_t, destroy, void,
95
  private_spinlock_t *this)
96
0
{
97
0
#ifdef HAVE_PTHREAD_SPIN_INIT
98
0
  profiler_cleanup(&this->profile);
99
0
  pthread_spin_destroy(&this->spinlock);
100
#else
101
  this->mutex->destroy(this->mutex);
102
#endif
103
0
  free(this);
104
0
}
105
106
/*
107
 * Described in header
108
 */
109
spinlock_t *spinlock_create()
110
0
{
111
0
  private_spinlock_t *this;
112
113
0
  INIT(this,
114
0
    .public = {
115
0
      .lock = _lock,
116
0
      .unlock = _unlock,
117
0
      .destroy = _destroy,
118
0
    },
119
0
  );
120
121
0
#ifdef HAVE_PTHREAD_SPIN_INIT
122
0
  pthread_spin_init(&this->spinlock, PTHREAD_PROCESS_PRIVATE);
123
0
  profiler_init(&this->profile);
124
#else
125
  this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
126
#endif
127
128
0
  return &this->public;
129
0
}