Organizing arctecture-specific and conditional code
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Organizing arctecture-specific and conditional code
I got bored of working on my C library for the last few months, so I've decided to try rewriting my kernel at the same time. I plan to make it well-organized, preemptive, portable, etc. (I had nearly no experience when writing it the first time), but I can't figure out the best way to organize conditional (i.e. architecture specific and test) code. For example, my thread structure will be completely different on different architectures, but it will have the same names for its utility functions. I've seen this done with lots of preprocessor macros, but that seems kind of ugly: it would be better if I could conditionally compile/link certain files (e.g. there would be a thread.c for x86 and thread.c for another arch etc.) but keep the same headers as a specification of their interface.
How is this normally done?
How is this normally done?
Re: Organizing arctecture-specific and conditional code
I'd have something like this:
[/size]
Code: Select all
/* sys/thread.h */
#include <sys/arch/thread.h>
struct thread *new_thread(int magic);
Code: Select all
/* sys/thread_arch.h */
/* Really arch/x86/sys/arch/thread_arch.h, arch/sparc/sys/arch/thread_arch.h, arch/mips... or what ever. */
struct thread {
float pi;
float next_pi;
};
Code: Select all
# Makefile
TARGET_ARCH= x86 # or what ever
SRCS= main.c
OBJS= ${SRCS:.c=.o}
CFLAGS+= -Iarch/${TARGET_ARCH}/
all: ${OBJS}
${CC} ${CFLAGS} ${OBJS}
Re: Organizing arctecture-specific and conditional code
I don't know if it is the best way but what I did was to not include any headers from my arch include folder but instead simply wrote extern declarations of the methods I wanted to be able to contact in the kernel header files that need to use them. As long as those methods exist when the linking occurs it will work. What files is actually linked together you decide with your Makefile.
Is this a possible answer? I perhaps didn't understand the question.
Is this a possible answer? I perhaps didn't understand the question.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
http://github.com/Jezze/fudge/
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: Organizing arctecture-specific and conditional code
@fonty: That would work for switching structure declarations per architecture, but I'm also trying to do that with whole functions. Something like this:
But my real question is whether this is the best way of switching between architectures (i.e. conditional compilation of whole files, which I've never seen), or if the best way is something like preprocessor "#if"s (which I have seen in places). My main concern is for the assembly that's bound to be in each architecture directory, which can't be easily combined with the C preprocessor, and will have to be only be assembled on the proper architecture anyway.
Code: Select all
/* sys/thread_arch.c */
/* really arch/x86/sys/thread_arch.c */
struct thread *new_thread(int magic) {
foo();
/* ... */
}
Code: Select all
/* sys/thread_arch.c */
/* really arch/arm/sys/thread_arch.c */
struct thread *new_thread(int magic) {
bar();
/* ... */
}
Re: Organizing arctecture-specific and conditional code
my $a = "architecture independent"
I'd have this kind of structure:
src/ - $a files
src/sys/ - $a header files
src/sys/thread.h - $a defines for threading, includes sys/arch/thread.h
src/arch/ - directory for each architecture
src/arch/x/sys/arch - headers for arch x
src/arch/x/sys/thread.h - threading defines for x
src/arch/x/src - source files for arch x
src/arch/x/src/thread.c - internal wizardry of threading on x
In Makefile I'd add needed paths to include path and add needed files to be compiled with type of wizardry depending on how many and which different flavours of make I want to support.
In my eyes choices are this quite branchy directory structure with with possibly a bit "unclean" Makefiles, or sodomizing preprocessor.
I'd have this kind of structure:
src/ - $a files
src/sys/ - $a header files
src/sys/thread.h - $a defines for threading, includes sys/arch/thread.h
src/arch/ - directory for each architecture
src/arch/x/sys/arch - headers for arch x
src/arch/x/sys/thread.h - threading defines for x
src/arch/x/src - source files for arch x
src/arch/x/src/thread.c - internal wizardry of threading on x
In Makefile I'd add needed paths to include path and add needed files to be compiled with type of wizardry depending on how many and which different flavours of make I want to support.
In my eyes choices are this quite branchy directory structure with with possibly a bit "unclean" Makefiles, or sodomizing preprocessor.
Last edited by fronty on Wed Aug 04, 2010 12:19 pm, edited 1 time in total.
Re: Organizing arctecture-specific and conditional code
I prefer all my files to have architecture(or whatever)-specific names or directories. The makefile is built to compile only one special set of non-architecture-specific filenames. A configure script gets an argument of which target you want to compile for, and copies architecture-named files to generic-named files, just before the makefile runs. This pretty much eliminates all ifdefs -- because too many of those make my head ache.
Re: Organizing arctecture-specific and conditional code
I notice that Linux has a single 'arch' directory at the top level with most of the arch specific stuff below it. I think a microkernel needs a different arrangement. The src tree for a microkernel builds a number of separate programs to make the system. Kernel, mm, vfs, drivers, etc are usually separate programs in different top level directories. It would break modularity to then have a single top level arch. My feeling is that each part of the system needs its own arch dirs. I suggest simply having x86, mips etc directories below kernel, mm, vfs etc. You will also probably need an empty top level include directory where arch-correct public headers are installed as the system is built.
I don't think this actually answers your original question, just my thoughts.
I don't think this actually answers your original question, just my thoughts.
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Organizing arctecture-specific and conditional code
Most microkernel components (servers, drivers) should not have to deal with anything architecture specific (at least not anything a few preprocessor directives can't handle). This could even be extended to the memory manager if it provides only scheduling and the kernel deals with the actual page tables.gerryg400 wrote:I notice that Linux has a single 'arch' directory at the top level with most of the arch specific stuff below it. I think a microkernel needs a different arrangement. The src tree for a microkernel builds a number of separate programs to make the system. Kernel, mm, vfs, drivers, etc are usually separate programs in different top level directories. It would break modularity to then have a single top level arch. My feeling is that each part of the system needs its own arch dirs. I suggest simply having x86, mips etc directories below kernel, mm, vfs etc. You will also probably need an empty top level include directory where arch-correct public headers are installed as the system is built.
I don't think this actually answers your original question, just my thoughts.
Re: Organizing arctecture-specific and conditional code
True. That's why i'm suggesting that there needn't be a top level arch directory. However there are at least 3 reasons to have arch specific code that I can think of. And they apply to any piece of code.Most microkernel components (servers, drivers) should not have to deal with anything architecture specific (at least not anything a few preprocessor directives can't handle). This could even be extended to the memory manager if it provides only scheduling and the kernel deals with the actual page tables.
1. When the arch is different and requires at least a little difference in the implementation, for example some parts of mm.
2. For primitives that just need to be implemented differently because the underlying cpu is different, like spinlocks etc.
3. When you're chasing efficiency and supply for e.g. an arch specific memcpy.
Linux just bundles these all together. I think that's not suitable for a microkernel.
If a trainstation is where trains stop, what is a workstation ?
Re: Organizing arctecture-specific and conditional code
Why just for a microkernel? A monolithic kernel too I would say.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
http://github.com/Jezze/fudge/
Re: Organizing arctecture-specific and conditional code
I was trying not to say that I think the Linux src tree is poorly organised.Why just for a microkernel? A monolithic kernel too I would say
If a trainstation is where trains stop, what is a workstation ?
-
- Posts: 22
- Joined: Thu Jul 15, 2010 11:47 pm
Re: Organizing arctecture-specific and conditional code
Split out the architectures in an arch-specific subdir, like so:
Then, use make to work the -Is and the -Ls. If you like, do something like this:
Then, use:
Now, your makefile can look like:
Architecture-specific stuff can be slurped in via VPATH, other paths by Make. If you
need to include arch-neutral include files of the same name from the arch-neutral dir,
from within your arch-specific header files, you might try the (non-portable):
--Corey
Code: Select all
arch/blah/include
arch/blah/include/sys
arch/blah/src/mm
arch/blah/src/snazzle
...
Code: Select all
src/mm
src/snazzle
include
include/sys
...
arch/blah/include
arch/blah/include/sys
arch/blah
arch/blah/src/mm
arch/blah/src/snazzle
...
Code: Select all
vpath %.c $(patsubst $(TOPDIR)/%,$(TOPDIR)/arch/$(ARCH)/%,$(CURDIR))
Code: Select all
LIB_OBJS := foo.o bar.o baz.o
LIBS := libdingbat.a
BIN_OBJS := hoobajoob.o
BINS := zazzer
INCLUDE := -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/include
${BINS} : ${BIN_OBJS} $(patsubst lib%.a,-l%,${LIBS})
${ARCH-}cc -o $@ $<
${LIBS} : ${LIB_OBJS}
${ARCH-}ar cru $@ $<
%.o : %.c
${ARCH-}cc ${INCLUDE} -c -o $@ $?
need to include arch-neutral include files of the same name from the arch-neutral dir,
from within your arch-specific header files, you might try the (non-portable):
Code: Select all
#include_next <frobnitz.h>
$ :(){ (:|:)& };: