Commit 14019691 authored by robertdavidgraham's avatar robertdavidgraham
Browse files

processor affinity

parent be50fcf1
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -224,6 +224,20 @@ transmit_thread(void *v) /*aka. scanning_thread() */

    LOG(1, "xmit: starting transmit thread #%u\n", parms->nic_index);

    /* Lock this thread to a CPU. Transmit threads are on even CPUs,
     * receive threads on odd CPUs */
    if (pixie_cpu_get_count() > 1) {
        unsigned cpu_count = pixie_cpu_get_count();
        unsigned cpu = parms->nic_index * 2;
        while (cpu >= cpu_count) {
            cpu -= cpu_count;
            cpu++;
        }
        pixie_cpu_set_affinity(cpu);
        //pixie_cpu_raise_priority();
    }


    /* Create the shuffler/randomizer. This creates the 'range' variable,
     * which is simply the number of IP addresses times the number of
     * ports */
@@ -407,6 +421,18 @@ receive_thread(void *v)

    LOG(1, "recv: start receive thread #%u\n", parms->nic_index);

    /* Lock this thread to a CPU. Transmit threads are on even CPUs,
     * receive threads on odd CPUs */
    if (pixie_cpu_get_count() > 1) {
        unsigned cpu_count = pixie_cpu_get_count();
        unsigned cpu = parms->nic_index * 2 + 1;
        while (cpu >= cpu_count) {
            cpu -= cpu_count;
            cpu++;
        }
        pixie_cpu_set_affinity(cpu);
    }

    /*
     * If configured, open a --pcap file for saving raw packets. This is
     * so that we can debug scans, but also so that we can look at the
+143 −0
Original line number Diff line number Diff line
#define _GNU_SOURCE
#include "pixie-threads.h"

#if defined(WIN32)
@@ -7,6 +8,8 @@
#if defined(__GNUC__)
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <errno.h>
#endif

#ifndef UNUSEDPARM
@@ -17,6 +20,146 @@
#endif
#endif

/****************************************************************************
 ****************************************************************************/
void
pixie_cpu_raise_priority()
{
#if defined WIN32
DWORD_PTR result;
	result = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
	if (result == 0) {
		fprintf(stderr, "set_priority: returned error win32:%u\n", (unsigned)GetLastError());
	}
#elif defined(__GNUC__)
	pthread_t thread = pthread_self();
    pthread_attr_t thAttr;
    int policy = 0;
    int max_prio_for_policy = 0;

    pthread_attr_init(&thAttr);
    pthread_attr_getschedpolicy(&thAttr, &policy);
    max_prio_for_policy = sched_get_priority_max(policy);


    pthread_setschedprio(thread, max_prio_for_policy);
    pthread_attr_destroy(&thAttr);
    return;

#endif
}

/****************************************************************************
 * Set the current thread (implicit) to run exclusively on the explicit
 * process.
 * http://en.wikipedia.org/wiki/Processor_affinity
 ****************************************************************************/
void
pixie_cpu_set_affinity(unsigned processor)
{
#if defined WIN32
	DWORD_PTR mask;
	DWORD_PTR result;
	if (processor > 0)
		processor--;
	mask = ((size_t)1)<<processor;

	//printf("mask(%u) = 0x%08x\n", processor, mask);
	result = SetThreadAffinityMask(GetCurrentThread(), mask);
	if (result == 0) {
		fprintf(stderr, "set_affinity: returned error win32:%u\n", (unsigned)GetLastError());
	}
#elif defined(__GNUC__)
	int x;
	pthread_t thread = pthread_self();
	cpu_set_t cpuset;

	CPU_ZERO(&cpuset);

	CPU_SET(processor+1, &cpuset);

	x = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
	if (x != 0) {
		fprintf(stderr, "set_affinity: returned error linux:%d\n", errno);
	}
#endif
}

/****************************************************************************
 ****************************************************************************/
unsigned
pixie_cpu_get_count()
{
#if defined WIN32
	/* WINDOWS - use GetProcessAffinityMask() function */
	size_t x;
#if defined _M_X64
	DWORD_PTR process_mask = 0;
	DWORD_PTR system_mask = 0;
#else
	unsigned long process_mask = 0;
	unsigned long system_mask = 0;
#endif
	unsigned count = 0;
	unsigned i;

	x = GetProcessAffinityMask(GetCurrentProcess(), &process_mask, &system_mask);
	if (x == 0) {
		printf("GetProcessAffinityMask() returned error %u\n", (unsigned)GetLastError());
		return 1;
	}
	for (i=0; i<32; i++) {
		if (system_mask & 1)
			count++;
		system_mask >>= 1;
	}
	if (count == 0)
		return 1;
	else
		return count;
#elif defined __APPLE__
	/* BSD - use sysctl() function */
		int x;
		int mib[2];
		size_t ncpu_length;
		int ncpu = 1;

		mib[0] = CTL_HW;
		mib[1] = HW_NCPU;
		ncpu_length = sizeof(ncpu);
		x = sysctl(mib, 2, &ncpu, &ncpu_length, NULL, 0);
		if (x == -1) {
		  perror("sysctl(HW_NCPU) failed");
		  return 1;
		} else
		  return (unsigned)ncpu;
#elif defined linux
	/* http://linux.die.net/man/2/sched_getaffinity */
	{
		pid_t pid;
		cpu_set_t mask;
		int err;
  
		/* Gegret our process ID */
		pid = getpid();

		/* Get list of available CPUs for our system */
		err = sched_getaffinity(pid, sizeof(mask), &mask);
		if (err) {
			perror("sched_getaffinity");
			return 1;
		} else {
			return CPU_COUNT(&mask);
		}
	}
#else
#error need to find CPU count
	/* UNKNOWN - Well, we don't know the type of system which means we won't
	 * be able to start multiple threads anyway, so just return '1' */
	return 1;
#endif
}

/****************************************************************************
 ****************************************************************************/
size_t
+4 −0
Original line number Diff line number Diff line
@@ -6,8 +6,12 @@
#include <intrin.h>
#endif

unsigned pixie_cpu_get_count();

size_t pixie_begin_thread(void (*worker_thread)(void*), unsigned flags, void *worker_data);

void pixie_cpu_set_affinity(unsigned processor);
void pixie_cpu_raise_priority();

void pixie_locked_subtract_u32(unsigned *lhs, unsigned rhs); 

+3 −0
Original line number Diff line number Diff line
@@ -141,6 +141,9 @@ pixie_usleep(uint64_t waitTime)

    start = pixie_gettime();

    if (waitTime > 1000)
        Sleep(waitTime/1000);

    while (pixie_gettime() - start < waitTime)
        ;
}
+0 −11
Original line number Diff line number Diff line
@@ -7,17 +7,6 @@
#include "masscan.h"
#include "unusedparm.h"

static int
matches_me(struct Output *out, unsigned ip, unsigned port)
{
    unsigned i;

    for (i=0; i<8; i++) {
        if (ip == out->nics[i].ip_me && port == out->nics[i].port_me)
            return 1;
    }
    return 0;
}


void handle_udp(struct Output *out, const unsigned char *px, unsigned length, struct PreprocessedInfo *parsed)