Skip to content

Commit

Permalink
Add port to macOS (OpenEtherCATsociety#286)
Browse files Browse the repository at this point in the history
* Port to macOS

This port to macOS is an amalgam of the existing Linux and Win32
ports. Consequently code is duplicated from each in this port:
primarily from win32 in oshw, and Linux is osal.

Synthesizing a shared common posix port, did not seem warranted given
the modest amount of code, and stable api.

This port uses the default pcap interface provided in the development
libraries shipped with XCode.

Limited testing on os releases: 10.13 and 10.14.

* fix possible race condition as for win32

See aed0f81

* fix spelling as for linux / win32

See 7beba91
  • Loading branch information
mockbutler authored and nakarlsson committed May 15, 2019
1 parent d16d81e commit 8124037
Show file tree
Hide file tree
Showing 8 changed files with 1,114 additions and 3 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ if(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_NO_WARNINGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
set(OS_LIBS wpcap.lib Packet.lib Ws2_32.lib Winmm.lib)
elseif(UNIX)
elseif(UNIX AND NOT APPLE)
set(OS "linux")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")
set(OS_LIBS pthread rt)
elseif(APPLE)
# This must come *before* linux or MacOSX will identify as Unix.
set(OS "macosx")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")
set(OS_LIBS pthread pcap)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "rt-kernel")
set(OS "rtk")
message("ARCH is ${ARCH}")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Windows (Visual Studio)
* `cmake .. -G "NMake Makefiles"`
* `nmake`

Linux
-----
Linux & macOS
--------------

* `mkdir build`
* `cd build`
Expand Down
144 changes: 144 additions & 0 deletions osal/macosx/osal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/

#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <osal.h>

#define USECS_PER_SEC 1000000

int osal_usleep (uint32 usec)
{
struct timespec ts;
ts.tv_sec = usec / USECS_PER_SEC;
ts.tv_nsec = (usec % USECS_PER_SEC) * 1000;
/* usleep is deprecated, use nanosleep instead */
return nanosleep(&ts, NULL);
}

int osal_gettimeofday(struct timeval *tv, struct timezone *tz)
{
struct timespec ts;
int return_value;
(void)tz; /* Not used */

/* Use clock_gettime to prevent possible live-lock.
* Gettimeofday uses CLOCK_REALTIME that can get NTP timeadjust.
* If this function preempts timeadjust and it uses vpage it live-locks.
* Also when using XENOMAI, only clock_gettime is RT safe */
return_value = clock_gettime(CLOCK_MONOTONIC, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / 1000;
return return_value;
}

ec_timet osal_current_time(void)
{
struct timeval current_time;
ec_timet return_value;

osal_gettimeofday(&current_time, 0);
return_value.sec = current_time.tv_sec;
return_value.usec = current_time.tv_usec;
return return_value;
}

void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
{
if (end->usec < start->usec) {
diff->sec = end->sec - start->sec - 1;
diff->usec = end->usec + 1000000 - start->usec;
}
else {
diff->sec = end->sec - start->sec;
diff->usec = end->usec - start->usec;
}
}

void osal_timer_start(osal_timert * self, uint32 timeout_usec)
{
struct timeval start_time;
struct timeval timeout;
struct timeval stop_time;

osal_gettimeofday(&start_time, 0);
timeout.tv_sec = timeout_usec / USECS_PER_SEC;
timeout.tv_usec = timeout_usec % USECS_PER_SEC;
timeradd(&start_time, &timeout, &stop_time);

self->stop_time.sec = stop_time.tv_sec;
self->stop_time.usec = stop_time.tv_usec;
}

boolean osal_timer_is_expired (osal_timert * self)
{
struct timeval current_time;
struct timeval stop_time;
int is_not_yet_expired;

osal_gettimeofday(&current_time, 0);
stop_time.tv_sec = self->stop_time.sec;
stop_time.tv_usec = self->stop_time.usec;
is_not_yet_expired = timercmp(&current_time, &stop_time, <);

return is_not_yet_expired == FALSE;
}

void *osal_malloc(size_t size)
{
return malloc(size);
}

void osal_free(void *ptr)
{
free(ptr);
}

int osal_thread_create(void *thandle, int stacksize, void *func, void *param)
{
int ret;
pthread_attr_t attr;
pthread_t *threadp;

threadp = thandle;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stacksize);
ret = pthread_create(threadp, &attr, func, param);
if(ret < 0)
{
return 0;
}
return 1;
}

int osal_thread_create_rt(void *thandle, int stacksize, void *func, void *param)
{
int ret;
pthread_attr_t attr;
struct sched_param schparam;
pthread_t *threadp;

threadp = thandle;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stacksize);
ret = pthread_create(threadp, &attr, func, param);
pthread_attr_destroy(&attr);
if(ret < 0)
{
return 0;
}
memset(&schparam, 0, sizeof(schparam));
schparam.sched_priority = 40;
ret = pthread_setschedparam(*threadp, SCHED_FIFO, &schparam);
if(ret < 0)
{
return 0;
}

return 1;
}
38 changes: 38 additions & 0 deletions osal/macosx/osal_defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/

#ifndef _osal_defs_
#define _osal_defs_

#ifdef __cplusplus
extern "C"
{
#endif

// define if debug printf is needed
//#define EC_DEBUG

#ifdef EC_DEBUG
#define EC_PRINT printf
#else
#define EC_PRINT(...) do {} while (0)
#endif

#ifndef PACKED
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#endif

#include <pthread.h>
#define OSAL_THREAD_HANDLE pthread_t *
#define OSAL_THREAD_FUNC void
#define OSAL_THREAD_FUNC_RT void

#ifdef __cplusplus
}
#endif

#endif
Loading

0 comments on commit 8124037

Please sign in to comment.