delphij's Chaos

选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……

29 Jan 2004

junsu's new PID allocation code

I have installed these code on my test box. Well… an automated patch mechanism would be better but the current approach is just ok.

The original code was ported from NetBSD, which was originally announced on March 11th, by David Laight. I will quote the original annoucement here:

“The main benefits are:

  • pid and pgrp lookup (by id) doesn’t require a search
  • no dependency on MAXUSERS
  • automatically scales well to large numbers of processes
  • small data footprint for small systems
  • ability to enumerate through all the processes without holding a lock
    for the entire duration, or having very messy locking rules.
    (the allproc list and p_list fields could be depracted later).
  • Largely MP clean

The basic idea is to ensure that you allocate a pid number which
references an empty slot in the lookup table. To do this a FIFO freelist
is linked through the free slots of the lookup table.
To avoid reusing pid numbers, the top bits of the pid are incremented
each time the slot is reused (the last value is kept in the table).
If the table is getting full (ie a pid would be reused in a relatively
small number of forks), then the table size is doubled.
Orphaned pgrps correctly stop the pid being reused, orphaned sessions
keep the pgrp allocated.

Below is the main part of the change, there are other bits lurking
in fork and exit. If people think this code is ok, I’ll sort out a
full diff against ‘current’ (and fix for sparc64).

(I’ve been running this code for months!)”

Traditionally, the BSD pid allocator uses a linear allocation policy, which does not scale well on MP case. If I was right, Linux 2.4.x (and older versions) and many other *nix systems are using the same approach, too. On Windows, the behavior is somewhat different - You can rarely see PIDs > 5000, and on *nix systems, it’s very common to see a PID at 90000 or even bigger, then it will bump back to a certain low number (e.g. 100).

The biggest benefit brought by the patch to FreeBSD, in my opinion, should be the scalablity.

An interesting behavior is that the new allocator will sometimes allocate PID < 100 to a newly forked process. Is this correct? I’m not sure… and I will post more results here.

Linux has already adopted a new PID allocator by sometime in 2.5.x (FIXME: 2.5.36? I may have to checkout from bk) days, as well as a new scheduler. William Lee Irwin III’s IRC talk about Generallized PID Hashing is here, it is an interesting discussion.

(to be continued…)


Archived: 2 Comments

delphij | January 29, 2004 4:02 PM

A simple forkbomb to test the PID allocation.

#include
#include

const int maxchild = 100;

int
main(){
int i;
pid_t pid;

printf(“Parent pid=%d, “, getpid());
fflush(stdout);

for(i=0; i< maxchild; i++){
pid = fork();
if(0==pid)
return;
else
printf((maxchild-1 == i)? “%d\n”:"%d, “, pid);
fflush(stdout);
}
}

The sample output:
Parent pid=1612, 717, 1614, 1615, 1488, 1873, 1746, 1619, 212, 1621, 1494, 1239, 2008, 1625, 1498, 2523, 2012, 1757, 2142, 735, 1504, 1505, 1506, 1507, 1508, 741, 1382, 1255, 744, 2793, 1514, 1515, 1516, 1517, 1518, 1903, 2032, 881, 1010, 2803, 2804, 1013, 118, 1527, 1792, 1793, 1794, 1795, 1796, 2053, 2566, 263, 776, 2057, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 2591, 288, 801, 1058, 803, 292, 1829, 1830, 1831, 1832, 1833, 1834, 811, 2860, 2861, 814, 559, 304, 305, 2866, 2867, 308, 1589, 2614, 311, 2360

Same binary on a 5.2-RELEASE box:
Parent pid=49116, 49117, 49118, 49119, 49120, 49121, 49122, 49123, 49124, 49125, 49126, 49127, 49128, 49129, 49130, 49131, 49132, 49133, 49134, 49135, 49136, 49137, 49138, 49139, 49140, 49141, 49142, 49143, 49144, 49145, 49146, 49147, 49148, 49149, 49150, 49151, 49152, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160, 49161, 49162, 49163, 49164, 49165, 49166, 49167, 49168, 49169, 49170, 49171, 49172, 49173, 49174, 49175, 49176, 49177, 49178, 49179, 49180, 49181, 49182, 49183, 49184, 49185, 49186, 49187, 49188, 49189, 49190, 49191, 49192, 49193, 49194, 49195, 49196, 49197, 49198, 49199, 49200, 49201, 49202, 49203, 49204, 49205, 49206, 49207, 49208, 49209, 49210, 49211, 49212, 49213, 49214, 49215, 49216

delphij | January 29, 2004 4:03 PM

Oops…

#include
#include

Shoud read

#include <stdio.h>
#include <unistd.h>