1f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd// https://bugs.kde.org/show_bug.cgi?id=228343
2f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
3f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <stdio.h>
4f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <stdlib.h>
5f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <sys/time.h>
6f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <signal.h>
7f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <libkern/OSAtomic.h>
8f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd#include <pthread.h>
9f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
10f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddOSSpinLock sl = OS_SPINLOCK_INIT;
11f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddtypedef void *(*worker_t)(void*);
12f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddtypedef void (*Sigaction)(int, siginfo_t *, void *);
13f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
14f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddint GLOB=0;
15f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
16f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddstatic void EnableSigprof(Sigaction SignalHandler) {
17f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd struct sigaction sa;
18f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd sa.sa_sigaction = SignalHandler;
19f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd sa.sa_flags = SA_RESTART | SA_SIGINFO;
20f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd sigemptyset(&sa.sa_mask);
21f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd if (sigaction(SIGPROF, &sa, NULL) != 0) {
22f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   perror("sigaction");
23f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   abort();
24f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd }
25f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd struct itimerval timer;
26f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd timer.it_interval.tv_sec = 0;
27f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd timer.it_interval.tv_usec = 1000000 / 10000;
28f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd timer.it_value = timer.it_interval;
29f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
30f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   perror("setitimer");
31f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   abort();
32f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd }
33f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd}
34f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
35f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddvoid *Worker() {
36fbfd7c6fdda008c6543c63d4ade222730d821edfrhyskidd long int i;
37fbfd7c6fdda008c6543c63d4ade222730d821edfrhyskidd for (i = 0; i < 100000000; i++) {
38f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   void *x = malloc((i % 64) + 1);
39f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd   free (x);
40f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd }
41f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd}
42f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
43f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddvoid SignalHandlerWithSpinlock(int sig, siginfo_t *siginfo, void *context) {
44f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd OSSpinLockLock(&sl);
45f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd GLOB++;
46f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd OSSpinLockUnlock(&sl);
47f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd}
48f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd
49f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskiddint main() {
50f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd EnableSigprof(SignalHandlerWithSpinlock);
51f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_t w_1;
52f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_t w_2;
53f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_create(&w_1, NULL, Worker, NULL);
54f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_create(&w_2, NULL, Worker, NULL);
55f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_join(w_1, NULL);
56f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd pthread_join(w_2, NULL);
57f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd printf("\tGLOB=%d\n", GLOB);
58f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd return 0;
59f6a6380f9bdf543b597a2739eca81d0bf148c255rhyskidd}
60