macOS support; thanks to @MrYadro

This should support ARM64 and x86-64.
-target flag based on information from
https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary#3618377.
This commit is contained in:
Andrew Udvare
2020-09-29 20:39:18 -04:00
committed by eray orçunus
parent 3435d6656c
commit d590fdddf6
4 changed files with 143 additions and 36 deletions

View File

@ -4,6 +4,7 @@
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
@ -21,6 +22,30 @@
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#ifdef __APPLE__
#define COMPAT_SEM_T sem_t *
int compat_sem_init(sem_t **ptr, __attribute__((unused)) int x, __attribute__((unused)) int y) {
*ptr = sem_open("/semaphore", O_CREAT, 0644, 1);
return *ptr == SEM_FAILED ? -1 : 0;
}
int compat_sem_post(sem_t **sem) {
return sem_post(*sem);
}
int compat_sem_wait(sem_t **sem) {
return sem_wait(*sem);
}
int compat_sem_destroy(sem_t **sem, const char * name) {
sem_close(*sem);
sem_unlink(name);
}
#else
#define COMPAT_SEM_T sem_t
#define compat_sem_post sem_post
#define compat_sem_destroy(x, y) sem_destroy(x)
#define compat_sem_init sem_init
#define compat_sem_wait sem_wait
#endif
// #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp)
bool flushStream[MAX_CDCHANNELS];
@ -35,11 +60,11 @@ struct CdReadInfo
int32 nStatus;
#ifdef ONE_THREAD_PER_CHANNEL
int8 nThreadStatus; // 0: created 1:initalized 2:abort now
pthread_t pChannelThread;
sem_t pStartSemaphore;
pthread_t pChannelThread;
COMPAT_SEM_T pStartSemaphore;
#endif
sem_t pDoneSemaphore; // used for CdStreamSync
int32 hFile;
COMPAT_SEM_T pDoneSemaphore; // used for CdStreamSync
int32 hFile;
};
char gCdImageNames[MAX_CDIMAGES+1][64];
@ -51,7 +76,7 @@ char *gImgNames[MAX_CDIMAGES];
#ifndef ONE_THREAD_PER_CHANNEL
pthread_t _gCdStreamThread;
sem_t gCdStreamSema; // released when we have new thing to read(so channel is set)
COMPAT_SEM_T gCdStreamSema; // released when we have new thing to read(so channel is set)
int8 gCdStreamThreadStatus; // 0: created 1:initalized 2:abort now
Queue gChannelRequestQ;
bool _gbCdStreamOverlapped;
@ -76,7 +101,7 @@ CdStreamInitThread(void)
gChannelRequestQ.tail = 0;
gChannelRequestQ.size = gNumChannels + 1;
ASSERT(gChannelRequestQ.items != nil );
status = sem_init(&gCdStreamSema, 0, 0);
status = compat_sem_init(&gCdStreamSema, 0, 0);
#endif
@ -91,7 +116,7 @@ CdStreamInitThread(void)
{
for ( int32 i = 0; i < gNumChannels; i++ )
{
status = sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0);
status = compat_sem_init(&gpReadInfo[i].pDoneSemaphore, 0, 0);
if (status == -1)
{
@ -100,7 +125,7 @@ CdStreamInitThread(void)
return;
}
#ifdef ONE_THREAD_PER_CHANNEL
status = sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0);
status = compat_sem_init(&gpReadInfo[i].pStartSemaphore, 0, 0);
if (status == -1)
{
@ -214,13 +239,13 @@ CdStreamShutdown(void)
// Destroying semaphores and free(gpReadInfo) will be done at threads
#ifndef ONE_THREAD_PER_CHANNEL
gCdStreamThreadStatus = 2;
sem_post(&gCdStreamSema);
compat_sem_post(&gCdStreamSema);
#endif
#ifdef ONE_THREAD_PER_CHANNEL
for ( int32 i = 0; i < gNumChannels; i++ ) {
gpReadInfo[i].nThreadStatus = 2;
sem_post(&gpReadInfo[i].pStartSemaphore);
compat_sem_post(&gpReadInfo[i].pStartSemaphore);
}
#endif
}
@ -254,10 +279,10 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
#ifndef ONE_THREAD_PER_CHANNEL
AddToQueue(&gChannelRequestQ, channel);
if ( sem_post(&gCdStreamSema) != 0 )
if ( compat_sem_post(&gCdStreamSema) != 0 )
printf("Signal Sema Error\n");
#else
if ( sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 )
if ( compat_sem_post(&gpReadInfo[channel].pStartSemaphore) != 0 )
printf("Signal Sema Error\n");
#endif
@ -332,7 +357,7 @@ CdStreamSync(int32 channel)
{
pChannel->bLocked = true;
sem_wait(&pChannel->pDoneSemaphore);
compat_sem_wait(&pChannel->pDoneSemaphore);
}
pChannel->bReading = false;
@ -383,12 +408,12 @@ void *CdStreamThread(void *param)
#ifndef ONE_THREAD_PER_CHANNEL
while (gCdStreamThreadStatus != 2) {
sem_wait(&gCdStreamSema);
compat_sem_wait(&gCdStreamSema);
int32 channel = GetFirstInQueue(&gChannelRequestQ);
#else
int channel = *((int*)param);
while (gpReadInfo[channel].nThreadStatus != 2){
sem_wait(&gpReadInfo[channel].pStartSemaphore);
compat_sem_wait(&gpReadInfo[channel].pStartSemaphore);
#endif
ASSERT( channel < gNumChannels );
@ -437,22 +462,22 @@ void *CdStreamThread(void *param)
if ( pChannel->bLocked )
{
sem_post(&pChannel->pDoneSemaphore);
compat_sem_post(&pChannel->pDoneSemaphore);
}
pChannel->bReading = false;
}
#ifndef ONE_THREAD_PER_CHANNEL
for ( int32 i = 0; i < gNumChannels; i++ )
{
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
}
sem_destroy(&gCdStreamSema);
for ( int32 i = 0; i < gNumChannels; i++ )
{
compat_sem_destroy(&gpReadInfo[i].pDoneSemaphore, "/semaphoredone");
}
compat_sem_destroy(&gCdStreamSema, "/semaphore");
free(gChannelRequestQ.items);
#else
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
compat_sem_destroy(&gpReadInfo[channel].pStartSemaphore, "/semaphorestart");
compat_sem_destroy(&gpReadInfo[channel].pDoneSemaphore, "/semaphoredone");
#endif
free(gpReadInfo);
free(gpReadInfo);
pthread_exit(nil);
}

View File

@ -81,7 +81,12 @@ DWORD _dwOperatingSystemVersion;
#include "resource.h"
#else
long _dwOperatingSystemVersion;
#ifndef __APPLE__
#include <sys/sysinfo.h>
#else
#include <mach/mach_host.h>
#include <sys/sysctl.h>
#endif
#include <stddef.h>
#include <locale.h>
#include <signal.h>
@ -449,15 +454,27 @@ psInitialize(void)
#endif
#endif
#ifndef __APPLE__
struct sysinfo systemInfo;
sysinfo(&systemInfo);
_dwMemAvailPhys = systemInfo.freeram;
_dwOperatingSystemVersion = OS_WINXP; // To fool other classes
debug("Physical memory size %u\n", systemInfo.totalram);
debug("Available physical memory %u\n", systemInfo.freeram);
#else
uint64_t size = 0;
uint64_t page_size = 0;
size_t uint64_len = sizeof(uint64_t);
size_t ull_len = sizeof(unsigned long long);
sysctl((int[]){CTL_HW, HW_PAGESIZE}, 2, &page_size, &ull_len, NULL, 0);
sysctl((int[]){CTL_HW, HW_MEMSIZE}, 2, &size, &uint64_len, NULL, 0);
vm_statistics_data_t vm_stat;
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &count);
_dwMemAvailPhys = (uint64_t)(vm_stat.free_count * page_size);
debug("Physical memory size %llu\n", _dwMemAvailPhys);
debug("Available physical memory %llu\n", size);
#endif
_dwOperatingSystemVersion = OS_WINXP; // To fool other classes
#endif
TheText.Unload();