Now you are getting a little closer to reality: You paid a guy a year to learn.

For your "A very good C programmer in general will do well enough.", that sounds wrong: C is just Brian W. Kernighan and Dennis M. Ritchie; sorry 'bout that; for "C", it's just that one, thin, 'idiosyncratic' book where I still can't make sense, parse the syntax, out of an arbitrary 'declare' (I borrow from PL/I since C likely has no good terminology) statement.

C in Kernighan and Ritchie is a DIRT SIMPLE language. In particular, there is NOTHING, not a single line anywhere, in the language on concurrency.

Being a "very good C programmer" is a bit vague: To get very far in C, about have to dig into material definitely not in the book and likely not standard or even well documented.

In C one place I started screaming was all their talk about "the heap" and malloc(). Their 'heap' likely has nothing to do with the heap data structure in 'heap sort', and they never said what their heap was or how malloc() worked. I've done things in dynamic storage allocation, and not knowing the details, ANY of the details, of what C does was a BUMMER. I couldn't hope to design serious software, especially for an operating system with concurrency, without knowing in fine detail just how malloc() and free() worked. Not a chance.

Note that Microsoft just gave up: They know that their Visual Basic .NET, C#, common language runtime (CLR), etc. just MUST work for long running, serious, production applications. So, there, first-cut, it is CRUCIAL to let programmers not have to worry about memory leaks. Second, even worse, Microsoft had to find some dynamic memory allocation that didn't have the memory of the application just grow slowly over the days and after two months have the program slow to a crawl or just die. So, they went for the gold standard solution: MOVE the data in memory and do full 'garbage collection'. Some questions remain, but so far my timings indicate that it at least mostly works. Just dynamic memory allocation AIN'T easy, ESPECIALLY in an operating system that we want to run for months or years.

Next, for threading in C, maybe go to the Posix things. Again, that's not really just C, i.e., as in Kernighan and Ritchie.

Next, in C there's the 'stack': To get very far using C, very much need to know a LOT about the details of 'the stack', especially for anything with concurrency in an operating system, but the details are not easy to find and likely not even standard. Uh, do some moving of data in memory and totally mess up some stack pointers!

E.g., I could never find any decently clear details from C compiler or linkage editor documentation on just what the 'stack limitations' were or anything about 'stack overflows'. All clear as mud. The hope is that such things just won't happen, and for serious code that's DUMB. Special case of a general situation: For serious software, even just in applications, CERTAINLY in an operating system, C is DUMB.

Then there's the really big elephant in the room on using C for concurrency in an operating system: WTF does C do with an interrupt or an exceptional condition? The broad problem is freeing various 'resources' and popping back the 'stack' of 'dynamic descendancy' (another term from PL/I internals), but Kernighan and Ritchie provide no documentation about C to let one design how to do such things.

So, as a serious language for concurrency and serious work, say, in an operating system, C just SUCKS because of lack of solid features and documentation. Write trivial little word whacking 'filters' as in Kernighan and Ritchie, sure. The last C I did was as Microsoft .NET 'unmanaged' code called from Visual Basic .NET 'managed' code using 'platform invoke' -- what I did looks solid enough, but I want to avoid that subject like a barrel of poisonous snakes.

If I'd had to do much with C, then I'd have screamed myself hoarse.

Somehow I suspect that concurrency has made progress past, say, just

C. A. R. Hoare, 'Communicating Sequential Processes',

now in PDF near the top of a Google search. So, if you want some expertise in concurrency, then get someone who had a recent, solid course in the subject, did well in it, has applied it, and maybe has done some serious work with it.

Concurrency is now a newly, very hot topic due to many cores, Web sites with tens of thousands of user 'sessions' at once, corresponding loads on data bases, MemCache, etc. The latest I heard was that there are some fairly serious concurrency bugs in some of the most important 'frameworks'. Going forward, doing much with concurrency will be a challenge. Such work will just scream out for some totally rock solid 'proofs of correctness' -- and major applications of keep it simple, stupid -- since there is no hope even in heaven of duplicating failures from bugs. Zip, zilch, zero hope.

Mostly what people are trying to do is to get some better concurrency 'primitives' way above interrupts with save and restore registers, spin locks, Mutexes, even 'transactional' topics like deadlock detection and resolution, and give programmers some robust, easy to use tools that actually work.

For how to modify an operating system, looks like you should get with whoever owns the operating system and what their 'guidelines' e.g., on concurrency primitives, etc., are for modifications.

Again, part of success is good problem selection. So, if you can't do all the significant technical work yourself, then either you didn't pick a very good project or have one boatload of money and time to recruit, select, hire, relocate, train, and manage people.