So FYI, it does look like Postgres built in 32-bit mode, at least
pointers are 32 bits. But I think maxalign might still be enough due
to doubles being 64 bits.

checking whether long int is 64 bits... no
checking whether long long int is 64 bits... yes
checking snprintf length modifier for long long int... ll
checking whether snprintf supports the %z modifier... yes
checking size of void *... 4
checking size of size_t... 4
checking size of long... 4
checking whether to build with float4 passed by value... yes
checking whether to build with float8 passed by value... no
checking alignment of short... 2
checking alignment of int... 4
checking alignment of long... 4
checking alignment of long long int... 8
checking alignment of double... 8
checking for int8... no
checking for uint8... no
checking for int64... no
checking for uint64... no
checking for __int128... no

I wrote a test program based on latch.c and tested various alignments.
It does indeed get EFAULT for anything other than 8-byte alignment
(the second argument is the number of bytes to offset the events
structure):

$ echo | ./a.out 1 0
epoll_wait(epfd=5, events=0x22018, maxevents=1, timeout=-1)
success
$ echo | ./a.out 1 1
epoll_wait(epfd=5, events=0x22019, maxevents=1, timeout=-1)
epoll_wait: Bad address
$ echo | ./a.out 1 2
epoll_wait(epfd=5, events=0x2201a, maxevents=1, timeout=-1)
epoll_wait: Bad address
$ echo | ./a.out 1 4
epoll_wait(epfd=5, events=0x2201c, maxevents=1, timeout=-1)
epoll_wait: Bad address

The same program gets success for any all offsets on x86.
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/epoll.h>

/* typedef in latch.h */
struct WaitEventSet
{
  int nevents;
  int nevents_space;
  int epoll_fd;
  struct epoll_event *epoll_ret_events;
};


int main(int argc, char *argv[], char *envp[]) {

  int rc;
  int nevents = 0;
  int align = 0;
  int size;
  struct WaitEventSet *set;

  if (argc >= 3)
    align = atoi(argv[2]);
  if (argc >= 2)
    nevents = atoi(argv[1]);

  size = sizeof(struct WaitEventSet);
  size += sizeof(struct epoll_event) * nevents;
  size += align;
  
  set = malloc(size);
  set->nevents = nevents;
  set->nevents_space = nevents;
  set->epoll_fd = rc = epoll_create(nevents);
  if (rc < 0) {
    perror("epoll_create");
    exit(1);
  }
  set->epoll_ret_events = (struct epoll_event*)(((char*)&set->epoll_ret_events) + sizeof(char *) + align);
  
  struct epoll_event event;
  event.events = EPOLLERR | EPOLLHUP | EPOLLIN;
  event.data.u64 = 0;
  rc = epoll_ctl(set->epoll_fd, EPOLL_CTL_ADD, 0, &event);
  if (rc < 0) {
    perror("epoll_ctl(epoll_ctl_add)");
    exit(1);
  }

  printf("epoll_wait(epfd=%d, events=%p, maxevents=%d, timeout=%d)\n",
	 set->epoll_fd, set->epoll_ret_events, nevents, -1);

  rc = epoll_wait(set->epoll_fd, set->epoll_ret_events, nevents, -1);
  if (rc < 0) {
    perror("epoll_wait");
    exit(1);
  }
  printf("success\n");
  exit(0);
}
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to