-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathlinux_port.c
More file actions
223 lines (186 loc) · 5.78 KB
/
linux_port.c
File metadata and controls
223 lines (186 loc) · 5.78 KB
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* linux_port.c
This file is part of a program that implements a Software-Defined Radio.
Copyright (C) 2013 Warren Pratt, NR0V and John Melton, G0ORX/N6LYT
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
The author can be reached by email at
warren@wpratt.com
john.d.melton@googlemail.com
*/
#include "linux_port.h"
#include "comm.h"
/********************************************************************************************************
* *
* Linux Port Utilities *
* *
********************************************************************************************************/
#if defined(linux) || defined(__APPLE__)
void QueueUserWorkItem(void *function,void *context,int flags) {
pthread_t t;
pthread_create(&t, NULL, function, context);
pthread_join(t, NULL);
}
void InitializeCriticalSectionAndSpinCount(pthread_mutex_t *mutex,int count) {
pthread_mutexattr_t mAttr;
pthread_mutexattr_init(&mAttr);
#ifdef __APPLE__
// DL1YCF: MacOS X does not have PTHREAD_MUTEX_RECURSIVE_NP
pthread_mutexattr_settype(&mAttr,PTHREAD_MUTEX_RECURSIVE);
#else
pthread_mutexattr_settype(&mAttr,PTHREAD_MUTEX_RECURSIVE_NP);
#endif
pthread_mutex_init(mutex,&mAttr);
pthread_mutexattr_destroy(&mAttr);
// ignore count
}
void EnterCriticalSection(pthread_mutex_t *mutex) {
pthread_mutex_lock(mutex);
}
void LeaveCriticalSection(pthread_mutex_t *mutex) {
pthread_mutex_unlock(mutex);
}
void DeleteCriticalSection(pthread_mutex_t *mutex) {
pthread_mutex_destroy(mutex);
}
int LinuxWaitForSingleObject(sem_t *sem,int ms) {
int result=0;
if(ms==INFINITE) {
// wait for the lock
result=sem_wait(sem);
} else {
// try to get the lock
result=sem_trywait(sem);
if(result!=0) {
// didn't get the lock
if(ms!=0) {
// sleep if ms not zero
Sleep(ms);
// try to get the lock again
result=sem_trywait(sem);
}
}
}
return result;
}
sem_t *LinuxCreateSemaphore(int attributes,int initial_count,int maximum_count,char *name) {
sem_t *sem;
#ifdef __APPLE__
//DL1YCF
//This routine is invoked with name=NULL several times, so we have to make
//a unique name of tpye WDSPxxxxx for each invocation.
static int semcount=0;
char sname[12];
sprintf(sname,"WDSP%05d",semcount++);
sem_unlink(sname);
sem=sem_open(sname, O_CREAT | O_EXCL, 0700, initial_count);
if (sem == SEM_FAILED) {
perror("WDSP:CreateSemaphore");
}
#else
sem=malloc(sizeof(sem_t));
int result;
result=sem_init(sem, 0, 0);
if (result < 0) {
perror("WDSP:CreateSemaphore");
}
#endif
return sem;
}
void LinuxReleaseSemaphore(sem_t* sem,int release_count, int* previous_count) {
while(release_count>0) {
sem_post(sem);
release_count--;
}
}
sem_t *CreateEvent(void* security_attributes,int bManualReset,int bInitialState,char* name) {
int result;
sem_t *sem;
sem=LinuxCreateSemaphore(0,0,0,0);
// need to handle bManualReset and bInitialState
return sem;
}
void LinuxSetEvent(sem_t* sem) {
sem_post(sem);
}
HANDLE wdsp_beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist) {
pthread_t threadid;
pthread_attr_t attr;
int rc = 0;
if (rc = pthread_attr_init(&attr)) {
return (HANDLE)-1;
}
if(stack_size!=0) {
if (rc = pthread_attr_setstacksize(&attr, stack_size)) {
return (HANDLE)-1;
}
}
if( rc = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED)) {
return (HANDLE)-1;
}
if (rc = pthread_create(&threadid, &attr, (void*(*)(void*))start_address, arglist)) {
return (HANDLE)-1;
}
//pthread_attr_destroy(&attr);
#ifndef __APPLE__
// DL1YCF: this function does not exist on MacOS. You can only name the
// current thread.
rc=pthread_setname_np(threadid, "WDSP");
#endif
return (HANDLE)threadid;
}
void _endthread() {
int res;
pthread_exit((void *)&res);
}
void SetThreadPriority(HANDLE thread, int priority) {
/*
int policy;
struct sched_param param;
pthread_getschedparam(thread, &policy, ¶m);
param.sched_priority = sched_get_priority_max(policy);
pthread_setschedparam(thread, policy, ¶m);
*/
}
int CloseHandle(HANDLE hObject) {
//
// This routine is *ONLY* called to release semaphores
//
#ifdef __APPLE__
//
// A semaphore is closed and re-allocated on each RX->TX transition.
// After about 200 RX/TX transitions, MacOS runs out of file descriptors
// since MacOS only has named semaphores. As a consequence,
// no new semaphores can be allocated, and other parts of the program cannot
// open new files ore make new connections.
// Therefore we should close the semaphore.
//
if (sem_close((sem_t *)hObject) < 0) {
perror("WDSP:CloseHandle:SemCLose");
}
#else
//
// Although the number of semaphores seems "unlimited" on RapianOS,
// this is nevertheless a memory leak (a sem_t is allocated before
// sem_init is called, see above).
// So destroy the semaphore and (if this was successful) release the memory.
//
if (sem_destroy((sem_t *)hObject) < 0) {
perror("WDSP:CloseHandle:SemDestroy");
} else {
// if sem_destroy failed, do not release storage
free(hObject);
}
#endif
// this is actually a void function (return value never used).
return 0;
}
#endif