summaryrefslogtreecommitdiff
blob: a8b32022e44bca425f8c61197d8515f89bdeb127 (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
fix from upstream

From 2a2743361cf643b9dd2ba3e491da62e7cb83a101 Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@fb.com>
Date: Mon, 29 Jun 2015 09:34:39 -0600
Subject: [PATCH] workqueue: make it work on platforms without
 __sync_fetch_and_add()

Signed-off-by: Jens Axboe <axboe@fb.com>
---
 configure   | 22 ++++++++++++++++++++++
 workqueue.c | 22 ++++++++++++++++++++++
 workqueue.h |  1 +
 3 files changed, 45 insertions(+)

diff --git a/configure b/configure
index e459d63..e5cf34d 100755
--- a/configure
+++ b/configure
@@ -271,6 +271,7 @@ CYGWIN*)
   output_sym "CONFIG_TCP_NODELAY"
   output_sym "CONFIG_TLS_THREAD"
   output_sym "CONFIG_IPV6"
+  output_sym "CONFIG_SFA"
   echo "CC=$CC" >> $config_host_mak
   echo "BUILD_CFLAGS=$CFLAGS -include config-host.h -D_GNU_SOURCE" >> $config_host_mak
   exit 0
@@ -1492,6 +1493,24 @@ if compile_prog "" "" "getmntinfo"; then
 fi
 echo "getmntinfo                    $getmntinfo"
 
+##########################################
+# Check whether we have __sync_fetch_and_add()
+sfa=="no"
+cat > $TMPC << EOF
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+int main(int argc, char **argv)
+{
+  uint64_t dst = 1, src = 3;
+  __sync_fetch_and_add(&dst, src);
+}
+EOF
+if compile_prog "" "" "__sync_fetch_and_add"; then
+  sfa="yes"
+fi
+echo "__sync_fetch_and_add          $sfa"
+
 #############################################################################
 
 if test "$wordsize" = "64" ; then
@@ -1671,6 +1690,9 @@ fi
 if test "$getmntinfo" = "yes" ; then
   output_sym "CONFIG_GETMNTINFO"
 fi
+if test "$sfa" = "yes" ; then
+  output_sym "CONFIG_SFA"
+fi
 
 if test "$zlib" = "no" ; then
   echo "Consider installing zlib-dev (zlib-devel), some fio features depend on it."
diff --git a/workqueue.c b/workqueue.c
index b9a967f..8f6963f 100644
--- a/workqueue.c
+++ b/workqueue.c
@@ -197,6 +197,7 @@ err:
 	return 1;
 }
 
+#ifdef CONFIG_SFA
 static void sum_val(uint64_t *dst, uint64_t *src)
 {
 	if (*src) {
@@ -204,15 +205,34 @@ static void sum_val(uint64_t *dst, uint64_t *src)
 		*src = 0;
 	}
 }
+#else
+static void sum_val(uint64_t *dst, uint64_t *src)
+{
+	if (*src) {
+		*dst += *src;
+		*src = 0;
+	}
+}
+#endif
 
 static void sum_ddir(struct thread_data *dst, struct thread_data *src,
 		     enum fio_ddir ddir)
 {
+#ifndef CONFIG_SFA
+	pthread_mutex_lock(&dst->io_wq.stat_lock);
+	pthread_mutex_lock(&src->io_wq.stat_lock);
+#endif
+
 	sum_val(&dst->io_bytes[ddir], &src->io_bytes[ddir]);
 	sum_val(&dst->io_blocks[ddir], &src->io_blocks[ddir]);
 	sum_val(&dst->this_io_blocks[ddir], &src->this_io_blocks[ddir]);
 	sum_val(&dst->this_io_bytes[ddir], &src->this_io_bytes[ddir]);
 	sum_val(&dst->bytes_done[ddir], &src->bytes_done[ddir]);
+
+#ifndef CONFIG_SFA
+	pthread_mutex_unlock(&src->io_wq.stat_lock);
+	pthread_mutex_unlock(&dst->io_wq.stat_lock);
+#endif
 }
 
 static void update_accounting(struct submit_worker *sw)
@@ -355,6 +375,7 @@ void workqueue_exit(struct workqueue *wq)
 	free(wq->workers);
 	pthread_mutex_destroy(&wq->flush_lock);
 	pthread_cond_destroy(&wq->flush_cond);
+	pthread_mutex_destroy(&wq->stat_lock);
 }
 
 static int start_worker(struct workqueue *wq, unsigned int index)
@@ -393,6 +414,7 @@ int workqueue_init(struct thread_data *td, struct workqueue *wq,
 	wq->next_free_worker = 0;
 	pthread_cond_init(&wq->flush_cond, NULL);
 	pthread_mutex_init(&wq->flush_lock, NULL);
+	pthread_mutex_init(&wq->stat_lock, NULL);
 
 	wq->workers = calloc(wq->max_workers, sizeof(struct submit_worker));
 
diff --git a/workqueue.h b/workqueue.h
index 5d47a5e..4e92449 100644
--- a/workqueue.h
+++ b/workqueue.h
@@ -17,6 +17,7 @@ struct workqueue {
 
 	pthread_cond_t flush_cond;
 	pthread_mutex_t flush_lock;
+	pthread_mutex_t stat_lock;
 	volatile int wake_idle;
 };
 
-- 
2.4.4