aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.cpp
blob: d4a5805e5114d103df197a329f653e41838a69bb (plain) (blame)
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
141
142
143
144
145
146
147
148
149
150
151

#include "stdafx.h"

#include "NativeUtils.h"

#include <string>
#ifndef _MSC_VER
#include <condition_variable>
#include <mutex>
#include <thread>
#endif

#include <cstdint>
#include <cstdlib>
#include <cstring>

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

OPENMPT_NAMESPACE_BEGIN

#ifndef _MSC_VER

namespace mpt {

class semaphore {
private:
	unsigned int count;
	unsigned int waiters_count;
	std::mutex mutex;
	std::condition_variable count_nonzero;
public:
	semaphore( unsigned int initial_count = 0 )
		: count(initial_count)
		, waiters_count(0)
	{
		return;
	}
	~semaphore() {
		return;
	}
	void wait() {
		std::unique_lock<std::mutex> l(mutex);
		waiters_count++;
		while ( count == 0 ) {
			count_nonzero.wait( l );
		}
		waiters_count--;
		count--;
	}
	void post() {
		std::unique_lock<std::mutex> l(mutex);
		if ( waiters_count > 0 ) {
			count_nonzero.notify_one();
		}
		count++;
	}
	void lock() {
		wait();
	}
	void unlock() {
		post();
	}
};

} // namespace mpt

#endif

OPENMPT_NAMESPACE_END

extern "C" {

OPENMPT_WINESUPPORT_API void * OPENMPT_WINESUPPORT_CALL OpenMPT_Alloc( size_t size ) {
	return calloc( 1, size );
}

OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Free( void * mem ) {
	if ( mem == nullptr ) {
		return;
	}
	free( mem );
	return;
}

OPENMPT_WINESUPPORT_API size_t OPENMPT_WINESUPPORT_CALL OpenMPT_String_Length( const char * str ) {
	size_t len = 0;
	if ( !str ) {
		return len;
	}
	len = strlen( str );
	return len;
}

OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_String_Duplicate( const char * src ) {
	if ( !src ) {
		return strdup( "" );
	}
	return strdup( src );
}

OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_String_Free( char * str ) {
	OpenMPT_Free( str );
}

typedef struct OpenMPT_Semaphore {
#ifndef _MSC_VER
	OPENMPT_NAMESPACE::mpt::semaphore * impl;
#else
	void * dummy;
#endif
} OpenMPT_Semaphore;

OPENMPT_WINESUPPORT_API OpenMPT_Semaphore * OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Construct(void) {
#ifndef _MSC_VER
	OpenMPT_Semaphore * sem = (OpenMPT_Semaphore*)OpenMPT_Alloc( sizeof( OpenMPT_Semaphore ) );
	sem->impl = new OPENMPT_NAMESPACE::mpt::semaphore(0);
	return sem;
#else
	return nullptr;
#endif
}

OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Destruct( OpenMPT_Semaphore * sem ) {
#ifndef _MSC_VER
	delete sem->impl;
	sem->impl = nullptr;
	OpenMPT_Free( sem );
#else
	MPT_UNREFERENCED_PARAMETER(sem);
#endif
}

OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Wait( OpenMPT_Semaphore * sem ) {
#ifndef _MSC_VER
	sem->impl->wait();
#else
	MPT_UNREFERENCED_PARAMETER(sem);
#endif
}

OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Post( OpenMPT_Semaphore * sem ) {
#ifndef _MSC_VER
	sem->impl->post();
#else
	MPT_UNREFERENCED_PARAMETER(sem);
#endif
}

} // extern "C"