| Gary,
The topics you have asked about, are as you can appreciate, difficult to
answer comprehensively in a few words. I will try and give you some
information but I would recommend that you study the documentation we provide
on our Documantation CD rom. There have also been some changes between Digital
unix V3.2x and V4.0(a/b). As you're starting from new, I'll stick to V4.0(a/b).
I need to look a bit further for info on your ISA programming question,
I'll get back to you when I have it. In the meantime here is some threads info
to be going on with.
There is a book in the programming section of the Doc CD entitled "Guide
to DECthreads" which comprehensively describes our current (and legacy) threads
implemtation, the scheduling philosphy's, the function calls and program
examples. Our recommendation is that for all new work, you use Pthreads, which
are Posix 1003.1c (1995) API complient. However we still support (for
compatibilty) the obsolete Posix 1003.4a (draft) API. I would reccomend you
peruse the documentaion above for an overall picture, but all the API's are
described in Unix man pages, if you installed them. The Pthread functions are
all called "pthread_<something>", so a "man -k pthread" will give you the list.
One point to be aware of is that from Digital Unix V4.0 onwards, there is no
longer a one-to-one relationship between Pthreads (user threads) and kernel
threads (which are shown by ps). The operating system runs kthreads as
required, and depending on the number of CPU's. It maps Pthreads onto kernel
threads as available, and there may be more than one Pthread mapped to a
kthread. The Ladebug debugger (and its GUI version, dxladebug) . has the
ability to attach to running processes and threads, and can be used for
debugging threaded applications. If you need to do performance tuning on your
application, then as well as the standard prof and pixie tools, there are
additional multi thread capable prof/pixie type tools in the Atom toolset (man
atom) , which is part of the OSFPGMR40x and OSFDE40x subsets.
hope this helps,
regards
Ian Chamberlin,
Digital Equipment Co, Software Partner Engineering.
===============000000000==============
Gary,
Regarding your device access question, our recommendation is that you
write a device driver for your ISA card. There is a whole section of books
about writing drivers on the documentation CD, I would sugest you start with
Writing Device Drivers:Tutorial and Writing EISA and ISA Bus Drivers.
I did look into alternatives (eg using mmap()) , but this doesn't seem
feasible.
regards
Ian Chamberlin,
Digital Equipment Co, Software Partner Engineering.
|
| Gary,
Regarding your device access question, our recommendation is that you
write a device driver for your ISA card. There is a whole section of books
about writing drivers on the documentation CD, I would sugest you start with
Writing Device Drivers:Tutorial and Writing EISA and ISA Bus Drivers.
I did look into alternatives (eg using mmap()) , but this doesn't seem
feasible.
regards
Ian Chamberlin,
Digital Equipment Co, Software Partner Engineering.
|
| Does the mmap() function allow us to map in a physical memory address
into a process's address space so that the process can write directly to
a physcial device? If we can't access I/O registers this way, then we
hope to create some memory registers that mirror the I/O ports (since we
also use this hardware in Intel-based platforms). If we cannot use the
mmap() function, is there one we can use or is this not possible at all? If
we cannot map the physical memory, then this will significantly increase
our porting time. If it won't work, please explain why. Please be as technical
as possible in your answer.
Thank-you for your time.
Gary.
===============================================================================
It is certainly refreshing to see that the kernel handles the thread
scheduling. Our last experience porting to HP-UX was somewhat
difficult and the performance is not near what we had hoped. This is
because they use library threads in which the kernel is unaware of the
threads within a process. It appears that even though yours is a version
of library threads, you have tweeked the kernel to handle the scheduling.
One question I had on threads that the docs did not explicitly answer
was a problem we ran into on HP-UX. We found that the thread-based
semaphores were not useable because they were not process-aware.
The data they used within the threads library was created locally within
the process.
This was a major problem due to our system architecture. We started
on a multi-threaded OS (OS/2) using DLLs (shared libraries). We
typically have a series of small executables that start the system with
the bulk of the code in shared libraries. These shared libraries often
start threads, create semaphores, etc. within one process. Other
processes (including) the starting process then call the API functions of
that shared library. The API code may add a request onto a queue (that
is protected by a process-and-thread aware semaphore) and then the
thread picks up the request when it gets processing time.
The problem with HP-UX was we could not use semop() because it
would suspend in the kernel and put the whole process to sleep
(including all threads). We had to kludge toghther our own semaphores
using a small assembly language segment that executed a single
instruction test-and-set operation. I picked up a similar segment of code
from your web site. This leads me to believe that your threads library
may also have this problem.
I know this was rather long-winded but I wanted to be sure you
understood why this was such a problem for us. Instead of being able
to use the kernel to suspend a running thread waiting on a semaphore
(very efficient since the user-process now does not need any execution
time), we have to go into a sleep-wakeup loop polling a shared-memory
location that all processes and threads can "see". This means the user
process never goes to sleep for any extended period of time, even if it
has nothing to do (very inefficient). Any assistance you can provide on
answering this question would be greatly appreciated.
In answer to some of the other topics: yes we will be using version 4.0
and yes we will be using the latest version of POSIX threads. We
always start with the latest product available from a vendor.
Gary,
|
| Gary
Sorry for the delay in answering your follow question, we were on holiday over
Easter, and I had to do some digging around to get answers.
Regarding your further question about threads, this is the answer from our
developers.
....
Until the forthcoming HP-UX 10.30, HP does not have "real" threads -- only
the OSF "DCE threads", which operate entirely in user-mode, with no support
(or knowledge) in the kernel. The user-mode thread library (which, by the
way, Digital originally wrote) uses select() and non-blocking I/O mode to
make "most" I/O operations appear to block only the calling thread. However,
that's only partly effective. UNIX typically "lies" about file system I/O,
for example, assuming that the file system cache makes all operations
"instantaneous" -- select() will never admit that the I/O will block. And, of
course, the method won't work for anything that's not supported by select(),
such as semaphores and message queues. Therefore, all such operations
unavoidably block the process.
Digital UNIX has true thread support. In fact, it's nearly impossible to
"block the process" in Digital UNIX, because there's really no such thing as
a process. (It's a set of data structures fabricated in the Mach kernel to
let the rest of the kernel pretend it's UNIX.) Digital UNIX does not schedule
"processes" -- it schedules threads. So, to block a process, some O/S code
would need to find the current Mach task, traverse a queue of threads
associated with that task, and block each of them individually. Of course it
can be done -- but it can't happen by accident or oversight! No standard
kernel blocking call (i.e., I/O operation) does this, so even those that
"don't know about threads" will still only block the calling thread.
.....
Just for your interest, I would add that as well as the statndard System V IPC
semaphores, we also have Posix P1003.1b semaphores - sem_xxxx These are
"counting semaphores", and tests I did some time back showed they were
considerbly quicker than the Sys V semop().
Regarding the i/o question, the reason why you can't use mmap() directly is
that you won't have a device entry point to open, and by this won't have a fd
to supply to the mmap system call.
You can apply the xxmmap function in your driver, but this requires some
knowledge of our I/O layout which is not generaly available, and is most likely
system dependent.
Also, as it says in sect 3.1.4 of the drivers tutorial, Alpha cpus don't
support the mmap system call for drivers. The reason is that the architecture
(until th e very lates release) has no hardware word or byte instructions, so
accesses to contiguous byte or word registers, or sparse i/o space can cause
corruption. That is why we recommend writing a device driver and using the
read_io_port, write_io_port, io_copyin and io_copyout instructions, which
overcome this problem.
Hope this answers your questions,
regards,
Ian.
|