LINUX.ORG.RU

gcc (не знаю как собрать)


0

1

Не судите строго! ос DEBIAN amd64 6.03 не знаю как собрать Буду Вам благодарен за пояснения!

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
 
#ifdef DEBUG
#define DEBUG_ONEMILLI          /* debug gameserver for 1000 us */
#endif
 
/* conversion */
#define ONE_SECOND      1000000000      /* 1 second in nanoseconds      */
#define ONE_MSECOND     1000000         /* 1 millisecond in nanoseconds */
#define ONE_USECOND     1000            /* 1 microsecond in nanoseconds */
#define ONE_MILLI       1000            /* 1 millisecond in microseconds*/
 
/* usleep */
#define USLEEP_CLATENCY 100000          /* check latency in usleep      */
#define USLEEP_LATENCY  50000           /* default latency in usleep    */
#define USLEEP_OVERHEAD 10500           /* overhead of usleep function  */
#define DELAY_TEST      3000            /* delay loop test              */
#define USLEEP_DELAY    50              /* usleep will use dealy        */
#define USLEEP_NONE     2               /* usleep is irrelevant         */
#define USLEEP_COUNT    1               /* default usleep count         */
 
static unsigned long usleep_avg_lat = USLEEP_LATENCY;
static unsigned long usleep_count = USLEEP_COUNT;
 
#ifdef DEBUG_ONEMILLI
unsigned long long debug_usleep_count = 0;
unsigned long long debug_usleep_last = 0;
unsigned long long debug_usleep_last_last = 0;
#endif
 
static unsigned long long get_nsecs(void)
{
        unsigned long long nsec;
        struct timespec ts;
 
        clock_gettime(CLOCK_MONOTONIC, &ts);
 
        nsec = ts.tv_sec;
        nsec = (nsec * ONE_SECOND) + ts.tv_nsec;
 
        return nsec;
}
 
static inline void loopdelay(unsigned long loops)
{
        /* This code is NOT portable */
        asm volatile(
                "test %0,%0\n"
                "jz 3f\n"
                "jmp 1f\n"
                ".align 16\n"
                "1:jmp 2f\n"
                ".align 16\n"
                "2:dec %0\n"
                "jnz 2b\n"
                "3:dec %0\n"
                : : "a" (loops)
        );
}
 
static void microdelay(unsigned long usecs)
{
        unsigned long long nsecs, nsecs_delay;
 
        nsecs = get_nsecs();
        usecs = usecs * ONE_USECOND;
        nsecs_delay = get_nsecs() - nsecs;
        /* If already timeout then return */
        if (nsecs_delay >= usecs)
                return;
 
        loopdelay(DELAY_TEST);
        nsecs = get_nsecs() - nsecs;
        /* if already timeout then return */
        if (nsecs >= usecs)
                return;
 
        nsecs_delay = nsecs - nsecs_delay - nsecs_delay;
 
        loopdelay((DELAY_TEST * (usecs - nsecs)) / nsecs_delay);
}
 
#ifdef DEBUG_ONEMILLI
void debug_onemill(unsigned long long nsecs)
{
        if (debug_usleep_count % ONE_MILLI == 0) {
                if (!debug_usleep_count) {
                        debug_usleep_last = nsecs;
                        debug_usleep_count++;
                        return;
                }
                debug_usleep_last_last = debug_usleep_last;
                debug_usleep_last = nsecs;
                printf("called usleep(%d) %d times in %10llu milliseconds\n",
                        ONE_MILLI, ONE_MILLI,
                        (debug_usleep_last - debug_usleep_last_last)/ONE_MSECOND);
        }
        debug_usleep_count++;
}
#endif
 
int usleep(__useconds_t usecs)
{
        unsigned long long nsecs;
        struct timespec ts;
        int ret = 0;
 
        /*
         * no usleep is required for less then USLEEP_DELAY
         * because even if we return it will fulfill usleep.
         */
        if (usecs < USLEEP_NONE)
                return ret;
 
        /*
         * usleep will use delay for less then USLEEP_DELAY
         * because if we go for sleep we will never come back before 70-80 usecs (even with SCHED_FIFO)
         */
        if (usecs < USLEEP_DELAY) {
                microdelay(usecs);
                return ret;
        }
 
        nsecs = get_nsecs();
#ifdef DEBUG_ONEMILLI
        if (usecs == ONE_MILLI)
                debug_onemill(nsecs);
#endif
        usecs = usecs * ONE_USECOND;
        /* 
         * CLOCK_MONOTONIC is faster to read than REALTIME, but REALTIME is more 
         * accurate.
         */
        clock_gettime(CLOCK_MONOTONIC, &ts);
        if (usecs > ONE_SECOND)
                ts.tv_sec += usecs / ONE_SECOND;
 
        /*
         * calculate real sleep value based on overhead and latency of usleep()
         */
        ts.tv_nsec += usecs - USLEEP_OVERHEAD - (usleep_avg_lat / usleep_count);
        if (ts.tv_nsec > ONE_SECOND) {
                ts.tv_sec++;
                ts.tv_nsec -= ONE_SECOND;
        }
 
        ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
        nsecs = get_nsecs() - nsecs - usecs;
 
        /*
         * check for valid latency
         */
        if (nsecs < USLEEP_CLATENCY) {
                usleep_avg_lat += nsecs;
                usleep_count++;
        }
 
        return ret;
}


А что надо собрать?

madcore ★★★★★
()

В этом файле отсутствует функция main, его можно преобразовать в объектный модуль, но без остальной программы он бесполезен.

gcc -c ./filename.c

m0rph ★★★★★
()
Ответ на: комментарий от wota

Благодарю, собралось. но по тому же принципу не собирается это.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdint.h>
#include <sched.h>
#include <unistd.h>
 
 
#include <assert.h>
#include <errno.h>
 
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
 
#include <linux/hpet.h>
#include <linux/rtc.h>
 
#define STACK_SIZE (1 * 1024 * 1024)
 
static struct
{
	int initialised; // 1 = use HPET, 2 = use CPU counter.
	int (*system_gettimeofday)(struct timeval *tp, void *tzp);
	struct timeval cachedTime;
	int frequency;
	int ticksPerUsec;
 
	int childPid;
	int parentPid;
 
	int fd;
	char* childStack;
 
} details;
static uint64_t lastTSCCount = -1;
 
static inline uint64_t RDTSC()
{
	unsigned long hi, lo;
	uint64_t result;
	__asm__ ("rdtsc" : "=a"(lo), "=d"(hi));
	result = ((uint64_t) hi << 32) | lo;
	return result;	
}
 
// Return ticks per usec.
static int calibrate()
{
	int i;
	unsigned long long startClock, endClock;
	struct timeval startTime, endTime;
	double t1, t2, diff;
 
	details.system_gettimeofday(&startTime, NULL);
	startClock = RDTSC();
 
	for (i = 0; i < 100000; ++i)
	{
		__asm__ __volatile__ ("nop");
	}
	details.system_gettimeofday(&endTime, NULL);
	endClock = RDTSC();
 
	t1 = startTime.tv_sec * 1000000.0 + startTime.tv_usec;
	t2 = endTime.tv_sec * 1000000.0 + endTime.tv_usec;
 
	diff = (endClock - startClock) / (t2 - t1);
 
	return diff + 0.5; // Round up to avoid time going backwards
}
 
 
static void
hpet_trigger(int dummy)
{
	details.system_gettimeofday(&details.cachedTime, NULL);
}
 
static int
hpet_thread(void* dummy)
{
	struct sigaction foo;
 
	// Dummy thread to accept HPET async signals
	// this should help to avoid interrupting sleep() calls and
	// friends in other threads.
 
	int result = -1;
	foo.sa_flags = SA_RESTART;
	sigemptyset(&foo.sa_mask);
	foo.sa_handler = hpet_trigger;
	result = sigaction(SIGIO, &foo, NULL);
	assert(result != -1);
	while(1)
	{
		pause();
	}
	return 0;
}
 
static int
init_hpet(int freq)
{
	int fdFlags;
	struct hpet_info info;
 
	// Child will have a new signal handler table, but share the same memory space
	// (new thread is created to avoid signal handler conflicts,
	// and to avoid waking the main thread up due to the hpet signals)
	details.childStack = malloc(STACK_SIZE);
	assert(details.childStack);
	details.childPid = clone(hpet_thread, details.childStack + STACK_SIZE - 64, CLONE_VM, NULL);
	if (details.childPid == -1)
	{
		goto out;
	}
 
	details.fd = open("/dev/hpet", O_RDONLY);
	if (details.fd < 0)
	{
		goto out;
	}
 
	if (ioctl(details.fd, HPET_IRQFREQ, freq) < 0) 
	{
		goto out;
	}
	if (ioctl(details.fd, HPET_INFO, &info) < 0)
	{
		goto out;
 
	}
	if (info.hi_flags && (ioctl(details.fd, HPET_EPI, 0) < 0)
			|| ioctl(details.fd, HPET_IE_ON, 0) < 0
		)
	{
		goto out;
	}
 
	if ((fcntl(details.fd, F_SETOWN, details.childPid) == -1) ||
		((fdFlags = fcntl(details.fd, F_GETFL)) == -1) ||
		(fcntl(details.fd, F_SETFL, fdFlags | O_ASYNC) == -1)) 
	{
		goto out;
	}
	return 1;
 
	out:
	if (details.fd >= 0) 
	{
		close(details.fd);
		details.fd = -1;
	}
	if (details.childPid != -1) 
	{
		kill(details.childPid, 15);
		waitpid(details.childPid, NULL, 0);
		details.childPid = -1;
	}
	if (details.childStack) 
	{
		free(details.childStack);
		details.childStack = NULL;
	}
	return 0;
}
 
 
static int
init_rtc(int freq)
{
	int fdFlags;
 
	// Child will have a new signal handler table, but share the same memory space
	// (new thread is created to avoid signal handler conflicts,
	// and to avoid waking the main thread up due to the hpet signals)
	details.childStack = malloc(STACK_SIZE);
	assert(details.childStack);
	details.childPid = clone(hpet_thread, details.childStack + STACK_SIZE - 64, CLONE_VM, NULL);
	if (details.childPid == -1)
	{
		goto out;
	}
 
	details.fd = open("/dev/rtc", O_RDONLY);
	if (details.fd < 0)
	{
		goto out;
	}
 
	if (ioctl(details.fd, RTC_IRQP_SET, freq) < 0)
	{
		goto out;
	}
	if (ioctl(details.fd, RTC_PIE_ON, 0) < 0)
	{
		goto out;
 
	}
 
	if ((fcntl(details.fd, F_SETOWN, details.childPid) == -1) ||
		((fdFlags = fcntl(details.fd, F_GETFL)) == -1) ||
		(fcntl(details.fd, F_SETFL, fdFlags | O_ASYNC) == -1)) 
	{
		goto out;
	}
	return 1;
 
	out:
	if (details.fd >= 0) 
	{
		close(details.fd);
		details.fd = -1;
	}
	if (details.childPid != -1) 
	{
		kill(details.childPid, 15);
		waitpid(details.childPid, NULL, 0);
		details.childPid = -1;
	}
	if (details.childStack) 
	{
		free(details.childStack);
		details.childStack = NULL;
	}
	return 0;
}
 
static void __attribute__((constructor))
init()
{
	char* msg;
	char* freqEnv;
	char* altEnv;
	int rawFreq;
 
	if (details.initialised)
	{
		fprintf(stderr, "libfasttime.so: Already initialised!\n");
	}
 
	details.initialised = 0;
	details.system_gettimeofday = NULL;
	details.cachedTime.tv_sec = 0;
	details.cachedTime.tv_usec = 0;
	details.frequency = 0;
	details.childPid = -1;
	details.parentPid = getpid();
	details.fd = -1;
	details.childStack = NULL;
	details.ticksPerUsec = 0;
 
	details.system_gettimeofday = dlsym(RTLD_NEXT, "gettimeofday");
	if ((msg = dlerror()) != NULL)
	{
		fprintf(stderr, "libfasttime.so: gettimeofday: dlopen failed: %s", msg);
		exit(1);
	}
 
	details.ticksPerUsec = calibrate();
	//fprintf(stderr, "Ticks per usec = %d\n", details.ticksPerUsec);
 
	freqEnv = getenv("FASTTIME_FREQ");
	if (freqEnv)
	{
		rawFreq = atoi(freqEnv);
	}
	else
	{
		rawFreq = 1024; // Hz
	}
	details.frequency = (rawFreq * 1e6) / details.ticksPerUsec;
 
	altEnv = getenv("FASTTIME_ALT");
	if (altEnv && *altEnv)
	{
		goto fallback;
	}
 
	if (init_hpet(rawFreq))
	{
		details.initialised = 1;
		fprintf(stderr, "libfasttime.so: initialized using hpet\n");
		goto out;
	}
	else if (init_rtc(rawFreq))
	{
		details.initialised = 1;
		fprintf(stderr, "libfasttime.so: initialized using rtc\n");
		goto out;
	}
 
	fallback:
	lastTSCCount = RDTSC();
	details.initialised = 2;
	fprintf(stderr, "libfasttime.so: using alternative time method\n");
 
	out:
	details.system_gettimeofday(&details.cachedTime, NULL);
 
}
 
static void __attribute__((destructor))
cleanup()
{
	if (details.fd >= 0) 
	{
		close(details.fd);
		details.fd = -1;
	}
	if (details.childStack) 
	{
		free(details.childStack);
		details.childStack = NULL;
	}
	if (details.childPid != -1) 
	{
		kill(details.childPid, 15);
		details.childPid = -1;
	}
}
 
 
int
gettimeofday(struct timeval *__restrict tp, __timezone_ptr_t tzp) // Copy declaration from sys/time.h
{
	if (details.initialised == 2)
	{
		uint64_t currentCount = RDTSC();
		int64_t diff = currentCount - lastTSCCount;
		if (diff > details.frequency || diff < 0)
		{
			details.system_gettimeofday(&details.cachedTime, tzp);
			lastTSCCount = currentCount;
		}
	}
	tp->tv_sec = details.cachedTime.tv_sec;
	tp->tv_usec = details.cachedTime.tv_usec;
 
	return 0;
}

Nippy
() автор топика
Ответ на: комментарий от m0rph
root@DDD:/home# gcc -shared -fPIC name.c -lrt -o name.so
name.c: In function ‘init’:
name.c:261: error: ‘RTLD_NEXT’ undeclared (first use in this function)
name.c:261: error: (Each undeclared identifier is reported only once
name.c:261: error: for each function it appears in.)
root@wazzup:/home# gcc -c ./name.c
Nippy
() автор топика
Ответ на: комментарий от Nippy

вы таки расскажите для чего это? если это файлы в одном проекте - то собирайте их в объектники и линкуйте вместе, если библиотеки для дебага - то в .so и подгружайте через LD_PRELOAD, так что это?

wota ★★
()
Ответ на: комментарий от Nippy

error: ‘RTLD_NEXT’ undeclared

добавь -D_GNU_SOURCE к ключам компилятора

wota ★★
()

Давай мы всем ЛОРом поработаем за тебя утилитой make

yurikoles ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.