1 /*************************************************************************/
2 /*  baked_light_baker_cmpxchg.cpp                                        */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #include "typedefs.h"
31 
32 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
33 
baked_light_baker_add_64f(double * dst,double value)34 void baked_light_baker_add_64f(double *dst, double value) {
35 
36 	union {
37 		int64_t i;
38 		double f;
39 	} swapy;
40 
41 	while (true) {
42 		swapy.f = *dst;
43 		int64_t from = swapy.i;
44 		swapy.f += value;
45 		int64_t to = swapy.i;
46 		if (__sync_bool_compare_and_swap((int64_t *)dst, from, to))
47 			break;
48 	}
49 }
50 
baked_light_baker_add_64i(int64_t * dst,int64_t value)51 void baked_light_baker_add_64i(int64_t *dst, int64_t value) {
52 
53 	while (!__sync_bool_compare_and_swap(dst, *dst, (*dst) + value)) {
54 	}
55 }
56 
57 #elif defined(WINDOWS_ENABLED)
58 
59 #include "windows.h"
60 
baked_light_baker_add_64f(double * dst,double value)61 void baked_light_baker_add_64f(double *dst, double value) {
62 
63 	union {
64 		int64_t i;
65 		double f;
66 	} swapy;
67 
68 	while (true) {
69 		swapy.f = *dst;
70 		int64_t from = swapy.i;
71 		swapy.f += value;
72 		int64_t to = swapy.i;
73 		int64_t result = InterlockedCompareExchange64((int64_t *)dst, to, from);
74 		if (result == from)
75 			break;
76 	}
77 }
78 
baked_light_baker_add_64i(int64_t * dst,int64_t value)79 void baked_light_baker_add_64i(int64_t *dst, int64_t value) {
80 
81 	while (true) {
82 		int64_t from = *dst;
83 		int64_t to = from + value;
84 		int64_t result = InterlockedCompareExchange64(dst, to, from);
85 		if (result == from)
86 			break;
87 	}
88 }
89 
90 #else
91 
92 //in goder (the god of programmers) we trust
93 #warning seems this platform or compiler does not support safe cmpxchg, your baked lighting may be funny
94 
baked_light_baker_add_64f(double * dst,double value)95 void baked_light_baker_add_64f(double *dst, double value) {
96 
97 	*dst += value;
98 }
99 
baked_light_baker_add_64i(int64_t * dst,int64_t value)100 void baked_light_baker_add_64i(int64_t *dst, int64_t value) {
101 
102 	*dst += value;
103 }
104 
105 #endif
106