tinycc/tests/tests2/114_bound_signal.c
grischka 64552b3faa
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
tccelf: rework linker_sym (_end/end) logic
- tcc_add_linker_symbols():
    don't add for dlls
- bind_exe_dynsym():
    update _end symbol when done
    allow data definition in the .so override a bss symbol
    in the exe. For example
       exe: int x;
       .so: int x = 123;
- set_elf_sym():
    cannot compare section numbers with symbols from dlls
  tcc_load_obj():
    return -1 from symbol conflict errors

tests/tests2/148_linker_symbols:
- use only one file
- make it print useful output rather than just "2 errors."
  In general, the tests2 setup with .expect files is meant
  to compare text output.  For example:
      printf("val = %d\n", val);

  .expect file can be generated or refreshed using
       make tests2.nnn+
   or in order to force generation with tcc itself
       make tests2.nnn+ GEN-CC='$(GEN-TCC)'

tccgen.c:
- __attribute__((section(...))) : set section type/flags
    according to first usage
- fix bcheck bounds for -fcommon
2026-08-05 17:41:23 +02:00

156 lines
2.8 KiB
C

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <setjmp.h>
static volatile int run = 1;
static sem_t sem;
static sem_t sem_child;
static void
add (int n)
{
int i;
int arr[n];
for (i = 0; i < n; i++) {
arr[i]++;
}
memset (&arr[0], 0, n * sizeof(int));
}
static void *
high_load (void *unused)
{
while (run) {
add(10);
add(20);
}
return NULL;
}
static void *
do_signal (void *unused)
{
while (run) {
kill (getpid(), SIGUSR1);
while (sem_wait(&sem) < 0 && errno == EINTR);
}
return NULL;
}
static void *
do_fork (void *unused)
{
pid_t pid;
while (run) {
switch ((pid = fork())) {
case 0:
add(1000);
add(2000);
exit(0);
break;
case -1:
return NULL;
default:
while (sem_wait(&sem_child) < 0 && errno == EINTR);
wait(NULL);
break;
}
}
return NULL;
}
static void signal_handler(int sig)
{
add(10);
add(20);
sem_post (&sem);
}
static void child_handler(int sig)
{
add(10);
add(20);
sem_post (&sem_child);
}
static unsigned getclock_ms(void)
{
#ifdef _WIN32
return GetTickCount();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
#endif
}
int
main (void)
{
int i;
pthread_t id1, id2, id3;
struct sigaction act;
sigjmp_buf sj;
sigset_t m;
time_t end;
memset (&act, 0, sizeof (act));
act.sa_handler = signal_handler;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
sigaction (SIGUSR1, &act, NULL);
act.sa_handler = child_handler;
sigaction (SIGCHLD, &act, NULL);
printf ("start\n"); fflush(stdout);
sem_init (&sem, 0, 0);
sem_init (&sem_child, 0, 0);
pthread_create(&id1, NULL, high_load, NULL);
pthread_create(&id2, NULL, do_signal, NULL);
#if !defined(__APPLE__)
pthread_create(&id3, NULL, do_fork, NULL);
#endif
/* sleep does not work !!! */
end = getclock_ms() + 200;
while (getclock_ms() < end) ;
run = 0;
pthread_join(id1, NULL);
pthread_join(id2, NULL);
#if !defined(__APPLE__)
pthread_join(id3, NULL);
#endif
sem_destroy (&sem);
sem_destroy (&sem_child);
printf ("end\n"); fflush(stdout);
sigemptyset (&m);
sigprocmask (SIG_SETMASK, &m, NULL);
if (sigsetjmp (sj, 0) == 0)
{
sigaddset (&m, SIGUSR1);
sigprocmask (SIG_SETMASK, &m, NULL);
siglongjmp (sj, 1);
printf ("failed");
return 1;
}
sigprocmask (SIG_SETMASK, NULL, &m);
if (!sigismember (&m, SIGUSR1))
printf ("failed");
return 0;
}