On Tue, Oct 22, 2019 at 01:51:50AM -0600, Anthony J. Bentley wrote:
> Stefan Sperling writes:
> > Storing the allocated size in a new field of cothread_t is not an option?
> 
> cothread_t is not a struct, it's void *, and there are cothread_t
> equality checks scattered throughout the code that make the diff
> larger.  That said, I don't see a better solution. Hopefully upstream
> will be amenable to it so we don't have to carry all these patches.

Thanks!

I have sent a link to this patch upstream. Let's see what they say.

> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/emulators/higan/Makefile,v
> retrieving revision 1.6
> diff -u -p -r1.6 Makefile
> --- Makefile  12 Jul 2019 20:46:09 -0000      1.6
> +++ Makefile  22 Oct 2019 07:50:17 -0000
> @@ -5,7 +5,7 @@ COMMENT =     multi-system Nintendo emulator
>  V =          106
>  DISTNAME =   higan_v$V-source
>  PKGNAME =    higan-$V
> -REVISION =   3
> +REVISION =   4
>  
>  USE_WXNEEDED =       Yes
>  
> Index: patches/patch-higan_emulator_scheduler_hpp
> ===================================================================
> RCS file: patches/patch-higan_emulator_scheduler_hpp
> diff -N patches/patch-higan_emulator_scheduler_hpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_emulator_scheduler_hpp        22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,36 @@
> +$OpenBSD$
> +
> +Index: higan/emulator/scheduler.hpp
> +--- higan/emulator/scheduler.hpp.orig
> ++++ higan/emulator/scheduler.hpp
> +@@ -63,7 +63,7 @@ struct Scheduler {
> +   }
> + 
> +   inline auto synchronize(Thread& thread) -> void {
> +-    if(thread.handle() == _master) {
> ++    if(thread.handle().data == _master.data) {
> +       while(enter(Mode::SynchronizeMaster) != Event::Synchronize);
> +     } else {
> +       _resume = thread.handle();
> +@@ -72,7 +72,7 @@ struct Scheduler {
> +   }
> + 
> +   inline auto synchronize() -> void {
> +-    if(co_active() == _master) {
> ++    if(co_active().data == _master.data) {
> +       if(_mode == Mode::SynchronizeMaster) return exit(Event::Synchronize);
> +     } else {
> +       if(_mode == Mode::SynchronizeSlave) return exit(Event::Synchronize);
> +@@ -80,9 +80,9 @@ struct Scheduler {
> +   }
> + 
> + private:
> +-  cothread_t _host = nullptr;    //program thread (used to exit scheduler)
> +-  cothread_t _resume = nullptr;  //resume thread (used to enter scheduler)
> +-  cothread_t _master = nullptr;  //primary thread (used to synchronize 
> components)
> ++  cothread_t _host = {0};    //program thread (used to exit scheduler)
> ++  cothread_t _resume = {0};  //resume thread (used to enter scheduler)
> ++  cothread_t _master = {0};  //primary thread (used to synchronize 
> components)
> +   Mode _mode = Mode::Run;
> +   Event _event = Event::Step;
> +   vector<Thread*> _threads;
> Index: patches/patch-higan_emulator_thread_hpp
> ===================================================================
> RCS file: patches/patch-higan_emulator_thread_hpp
> diff -N patches/patch-higan_emulator_thread_hpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_emulator_thread_hpp   22 Oct 2019 07:50:17 -0000
> @@ -0,0 +1,36 @@
> +$OpenBSD$
> +
> +Index: higan/emulator/thread.hpp
> +--- higan/emulator/thread.hpp.orig
> ++++ higan/emulator/thread.hpp
> +@@ -6,10 +6,10 @@ struct Thread {
> +   enum : uintmax { Second = (uintmax)-1 >> 1 };
> + 
> +   virtual ~Thread() {
> +-    if(_handle) co_delete(_handle);
> ++    if(_handle.data) co_delete(_handle);
> +   }
> + 
> +-  inline auto active() const { return co_active() == _handle; }
> ++  inline auto active() const { return co_active().data == _handle.data; }
> +   inline auto handle() const { return _handle; }
> +   inline auto frequency() const { return _frequency; }
> +   inline auto scalar() const { return _scalar; }
> +@@ -29,7 +29,7 @@ struct Thread {
> +   }
> + 
> +   auto create(auto (*entrypoint)() -> void, double frequency) -> void {
> +-    if(_handle) co_delete(_handle);
> ++    if(_handle.data) co_delete(_handle);
> +     _handle = co_create(64 * 1024 * sizeof(void*), entrypoint);
> +     setFrequency(frequency);
> +     setClock(0);
> +@@ -46,7 +46,7 @@ struct Thread {
> +   }
> + 
> + protected:
> +-  cothread_t _handle = nullptr;
> ++  cothread_t _handle = {0};
> +   uintmax _frequency = 0;
> +   uintmax _scalar = 0;
> +   uintmax _clock = 0;
> Index: patches/patch-higan_fc_controller_controller_cpp
> ===================================================================
> RCS file: patches/patch-higan_fc_controller_controller_cpp
> diff -N patches/patch-higan_fc_controller_controller_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_fc_controller_controller_cpp  22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/fc/controller/controller.cpp
> +--- higan/fc/controller/controller.cpp.orig
> ++++ higan/fc/controller/controller.cpp
> +@@ -7,7 +7,7 @@ ControllerPort controllerPort2;
> + #include "gamepad/gamepad.cpp"
> + 
> + Controller::Controller(uint port) : port(port) {
> +-  if(!handle()) create(Controller::Enter, 1);
> ++  if(!handle().data) create(Controller::Enter, 1);
> + }
> + 
> + Controller::~Controller() {
> Index: patches/patch-higan_md_controller_controller_cpp
> ===================================================================
> RCS file: patches/patch-higan_md_controller_controller_cpp
> diff -N patches/patch-higan_md_controller_controller_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_md_controller_controller_cpp  22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/md/controller/controller.cpp
> +--- higan/md/controller/controller.cpp.orig
> ++++ higan/md/controller/controller.cpp
> +@@ -9,7 +9,7 @@ ControllerPort extensionPort;
> + #include "fighting-pad/fighting-pad.cpp"
> + 
> + Controller::Controller(uint port) : port(port) {
> +-  if(!handle()) create(Controller::Enter, 1);
> ++  if(!handle().data) create(Controller::Enter, 1);
> + }
> + 
> + Controller::~Controller() {
> Index: patches/patch-higan_ms_controller_controller_cpp
> ===================================================================
> RCS file: patches/patch-higan_ms_controller_controller_cpp
> diff -N patches/patch-higan_ms_controller_controller_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_ms_controller_controller_cpp  22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/ms/controller/controller.cpp
> +--- higan/ms/controller/controller.cpp.orig
> ++++ higan/ms/controller/controller.cpp
> +@@ -7,7 +7,7 @@ ControllerPort controllerPort2;
> + #include "gamepad/gamepad.cpp"
> + 
> + Controller::Controller(uint port) : port(port) {
> +-  if(!handle()) create(Controller::Enter, 100);
> ++  if(!handle().data) create(Controller::Enter, 100);
> + }
> + 
> + Controller::~Controller() {
> Index: patches/patch-higan_pce_controller_controller_cpp
> ===================================================================
> RCS file: patches/patch-higan_pce_controller_controller_cpp
> diff -N patches/patch-higan_pce_controller_controller_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_pce_controller_controller_cpp 22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/pce/controller/controller.cpp
> +--- higan/pce/controller/controller.cpp.orig
> ++++ higan/pce/controller/controller.cpp
> +@@ -6,7 +6,7 @@ ControllerPort controllerPort;
> + #include "gamepad/gamepad.cpp"
> + 
> + Controller::Controller() {
> +-  if(!handle()) create(Controller::Enter, 1);
> ++  if(!handle().data) create(Controller::Enter, 1);
> + }
> + 
> + Controller::~Controller() {
> Index: patches/patch-higan_sfc_controller_controller_cpp
> ===================================================================
> RCS file: patches/patch-higan_sfc_controller_controller_cpp
> diff -N patches/patch-higan_sfc_controller_controller_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_sfc_controller_controller_cpp 22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/sfc/controller/controller.cpp
> +--- higan/sfc/controller/controller.cpp.orig
> ++++ higan/sfc/controller/controller.cpp
> +@@ -11,7 +11,7 @@ ControllerPort controllerPort2;
> + #include "justifier/justifier.cpp"
> + 
> + Controller::Controller(uint port) : port(port) {
> +-  if(!handle()) create(Controller::Enter, 1);
> ++  if(!handle().data) create(Controller::Enter, 1);
> + }
> + 
> + Controller::~Controller() {
> Index: patches/patch-higan_sfc_expansion_expansion_cpp
> ===================================================================
> RCS file: patches/patch-higan_sfc_expansion_expansion_cpp
> diff -N patches/patch-higan_sfc_expansion_expansion_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-higan_sfc_expansion_expansion_cpp   22 Oct 2019 07:50:17 
> -0000
> @@ -0,0 +1,14 @@
> +$OpenBSD$
> +
> +Index: higan/sfc/expansion/expansion.cpp
> +--- higan/sfc/expansion/expansion.cpp.orig
> ++++ higan/sfc/expansion/expansion.cpp
> +@@ -5,7 +5,7 @@ namespace SuperFamicom {
> + ExpansionPort expansionPort;
> + 
> + Expansion::Expansion() {
> +-  if(!handle()) create(Expansion::Enter, 1);
> ++  if(!handle().data) create(Expansion::Enter, 1);
> + }
> + 
> + Expansion::~Expansion() {
> Index: patches/patch-libco_amd64_c
> ===================================================================
> RCS file: patches/patch-libco_amd64_c
> diff -N patches/patch-libco_amd64_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libco_amd64_c       22 Oct 2019 07:50:17 -0000
> @@ -0,0 +1,74 @@
> +$OpenBSD$
> +
> +Index: libco/amd64.c
> +--- libco/amd64.c.orig
> ++++ libco/amd64.c
> +@@ -10,8 +10,8 @@ extern "C" {
> + #endif
> + 
> + static thread_local long long co_active_buffer[64];
> +-static thread_local cothread_t co_active_handle = 0;
> +-static void (*co_swap)(cothread_t, cothread_t) = 0;
> ++static thread_local cothread_t co_active_handle = {0};
> ++static void (*co_swap)(void *, void *) = 0;
> + 
> + #ifdef LIBCO_MPROTECT
> +   alignas(4096)
> +@@ -116,37 +116,47 @@ static void crash() {
> + }
> + 
> + cothread_t co_active() {
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   return co_active_handle;
> + }
> + 
> + cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
> +-  cothread_t handle;
> ++  cothread_t *handle = malloc(sizeof *handle);
> ++  if(!handle) {
> ++    err(1, "libco malloc failed");
> ++  }
> +   if(!co_swap) {
> +     co_init();
> +-    co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
> ++    co_swap = (void (*)(void *, void *))co_swap_function;
> +   }
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   size += 512;  /* allocate additional space for storage */
> +   size &= ~15;  /* align stack to 16-byte boundary */
> + 
> +-  if(handle = (cothread_t)malloc(size)) {
> +-    long long *p = (long long*)((char*)handle + size);  /* seek to top of 
> stack */
> ++  handle->data = mmap(0, size, PROT_READ|PROT_WRITE, 
> MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0);
> ++  if(handle->data == MAP_FAILED) {
> ++    err(1, "libco mmap failed");
> ++  } else {
> ++    long long *p = (long long*)((char*)handle->data + size);  /* seek to 
> top of stack */
> +     *--p = (long long)crash;                            /* crash if 
> entrypoint returns */
> +     *--p = (long long)entrypoint;                       /* start of 
> function */
> +-    *(long long*)handle = (long long)p;                 /* stack pointer */
> ++    *(long long*)handle->data = (long long)p;                 /* stack 
> pointer */
> +   }
> + 
> +-  return handle;
> ++  handle->size = size;
> ++
> ++  return *handle;
> + }
> + 
> + void co_delete(cothread_t handle) {
> +-  free(handle);
> ++  munmap(handle.data, handle.size);
> ++  free(&handle);
> + }
> + 
> + void co_switch(cothread_t handle) {
> +   register cothread_t co_previous_handle = co_active_handle;
> +-  co_swap(co_active_handle = handle, co_previous_handle);
> ++  co_active_handle = handle;
> ++  co_swap(co_active_handle.data, co_previous_handle.data);
> + }
> + 
> + #ifdef __cplusplus
> Index: patches/patch-libco_arm_c
> ===================================================================
> RCS file: patches/patch-libco_arm_c
> diff -N patches/patch-libco_arm_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libco_arm_c 22 Oct 2019 07:50:17 -0000
> @@ -0,0 +1,74 @@
> +$OpenBSD$
> +
> +Index: libco/arm.c
> +--- libco/arm.c.orig
> ++++ libco/arm.c
> +@@ -12,8 +12,8 @@ extern "C" {
> + #endif
> + 
> + static thread_local unsigned long co_active_buffer[64];
> +-static thread_local cothread_t co_active_handle = 0;
> +-static void (*co_swap)(cothread_t, cothread_t) = 0;
> ++static thread_local cothread_t co_active_handle = {0};
> ++static void (*co_swap)(void *, void *) = 0;
> + 
> + #ifdef LIBCO_MPROTECT
> +   alignas(4096)
> +@@ -36,36 +36,46 @@ static void co_init() {
> + }
> + 
> + cothread_t co_active() {
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   return co_active_handle;
> + }
> + 
> + cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
> +-  unsigned long* handle = 0;
> ++  cothread_t *handle = malloc(sizeof *handle);
> ++  if(!handle) {
> ++    err(1, "libco malloc failed");
> ++  }
> +   if(!co_swap) {
> +     co_init();
> +-    co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
> ++    co_swap = (void (*)(void *, void *))co_swap_function;
> +   }
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   size += 256;
> +   size &= ~15;
> + 
> +-  if(handle = (unsigned long*)malloc(size)) {
> +-    unsigned long* p = (unsigned long*)((unsigned char*)handle + size);
> +-    handle[8] = (unsigned long)p;
> +-    handle[9] = (unsigned long)entrypoint;
> ++  handle->data = (unsigned long*)mmap(0, size, PROT_READ|PROT_WRITE, 
> MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0);
> ++  if(handle->data == MAP_FAILED) {
> ++    err(1, "libco mmap failed");
> ++  } else {
> ++    unsigned long* p = (unsigned long*)((unsigned char*)handle->data + 
> size);
> ++    handle->data[8] = (unsigned long)p;
> ++    handle->data[9] = (unsigned long)entrypoint;
> +   }
> + 
> +-  return handle;
> ++  handle->size = size;
> ++
> ++  return *handle;
> + }
> + 
> + void co_delete(cothread_t handle) {
> +-  free(handle);
> ++  munmap(handle.data, handle.size);
> ++  free(&handle);
> + }
> + 
> + void co_switch(cothread_t handle) {
> +   cothread_t co_previous_handle = co_active_handle;
> +-  co_swap(co_active_handle = handle, co_previous_handle);
> ++  co_active_handle = handle;
> ++  co_swap(handle.data, co_previous_handle.data);
> + }
> + 
> + #ifdef __cplusplus
> Index: patches/patch-libco_libco_h
> ===================================================================
> RCS file: patches/patch-libco_libco_h
> diff -N patches/patch-libco_libco_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libco_libco_h       22 Oct 2019 07:50:17 -0000
> @@ -0,0 +1,23 @@
> +$OpenBSD$
> +
> +Index: libco/libco.h
> +--- libco/libco.h.orig
> ++++ libco/libco.h
> +@@ -7,11 +7,16 @@
> + #ifndef LIBCO_H
> + #define LIBCO_H
> + 
> ++#include <err.h>
> ++
> + #ifdef __cplusplus
> + extern "C" {
> + #endif
> + 
> +-typedef void* cothread_t;
> ++typedef struct {
> ++  void * data;
> ++  unsigned int size;
> ++} cothread_t;
> + 
> + cothread_t co_active();
> + cothread_t co_create(unsigned int, void (*)(void));
> Index: patches/patch-libco_ppc_c
> ===================================================================
> RCS file: patches/patch-libco_ppc_c
> diff -N patches/patch-libco_ppc_c
> Index: patches/patch-libco_x86_c
> ===================================================================
> RCS file: patches/patch-libco_x86_c
> diff -N patches/patch-libco_x86_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libco_x86_c 22 Oct 2019 07:50:17 -0000
> @@ -0,0 +1,74 @@
> +$OpenBSD$
> +
> +Index: libco/x86.c
> +--- libco/x86.c.orig
> ++++ libco/x86.c
> +@@ -18,8 +18,8 @@ extern "C" {
> + #endif
> + 
> + static thread_local long co_active_buffer[64];
> +-static thread_local cothread_t co_active_handle = 0;
> +-static void (fastcall *co_swap)(cothread_t, cothread_t) = 0;
> ++static thread_local cothread_t co_active_handle = {0};
> ++static void (fastcall *co_swap)(void *, void *) = 0;
> + 
> + #ifdef LIBCO_MPROTECT
> +   alignas(4096)
> +@@ -70,37 +70,47 @@ static void crash() {
> + }
> + 
> + cothread_t co_active() {
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   return co_active_handle;
> + }
> + 
> + cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
> +-  cothread_t handle;
> ++  cothread_t *handle = malloc(sizeof *handle);
> ++  if(!handle) {
> ++    err(1, "libco malloc failed");
> ++  }
> +   if(!co_swap) {
> +     co_init();
> +-    co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
> ++    co_swap = (void (fastcall*)(void *, void *))co_swap_function;
> +   }
> +-  if(!co_active_handle) co_active_handle = &co_active_buffer;
> ++  if(!co_active_handle.data) co_active_handle.data = &co_active_buffer;
> +   size += 256;  /* allocate additional space for storage */
> +   size &= ~15;  /* align stack to 16-byte boundary */
> + 
> +-  if(handle = (cothread_t)malloc(size)) {
> +-    long *p = (long*)((char*)handle + size);  /* seek to top of stack */
> ++  handle->data = mmap(0, size, PROT_READ|PROT_WRITE, 
> MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0);
> ++  if(handle->data == MAP_FAILED) {
> ++    err(1, "libco mmap failed");
> ++  } else {
> ++    long *p = (long*)((char*)handle->data + size);  /* seek to top of stack 
> */
> +     *--p = (long)crash;                       /* crash if entrypoint 
> returns */
> +     *--p = (long)entrypoint;                  /* start of function */
> +-    *(long*)handle = (long)p;                 /* stack pointer */
> ++    *(long*)handle->data = (long)p;                 /* stack pointer */
> +   }
> + 
> +-  return handle;
> ++  handle->size = size;
> ++
> ++  return *handle;
> + }
> + 
> + void co_delete(cothread_t handle) {
> +-  free(handle);
> ++  munmap(handle.data, handle.size);
> ++  free(&handle);
> + }
> + 
> + void co_switch(cothread_t handle) {
> +   register cothread_t co_previous_handle = co_active_handle;
> +-  co_swap(co_active_handle = handle, co_previous_handle);
> ++  co_active_handle = handle;
> ++  co_swap(co_active_handle.data, co_previous_handle.data);
> + }
> + 
> + #ifdef __cplusplus
> 
> 

Reply via email to