[HN Gopher] Hcreate(3)
       ___________________________________________________________________
        
       Hcreate(3)
        
       Author : luu
       Score  : 37 points
       Date   : 2024-08-12 00:21 UTC (1 days ago)
        
 (HTM) web link (linux.die.net)
 (TXT) w3m dump (linux.die.net)
        
       | ropejumper wrote:
       | Does someone know why these are not reentrant without the GNU
       | extension? It seems like a really weird choice to make a library
       | for hash tables and then make the state global like that.
        
         | kragen wrote:
         | probably they were added in 2.9bsd or something when programs
         | couldn't be more than about 5000 lines of code before you ran
         | out of the 16-bit address space
         | 
         | hmm, no, it doesn't seem to be in
         | https://www.tuhs.org/Archive/Distributions/UCB/2.9BSD/ or even
         | in https://www.tuhs.org/Archive/Distributions/UCB/4.2BSD/ or
         | https://www.tuhs.org/Archive/Distributions/UCB/4.3BSD/. and
         | https://man.freebsd.org/cgi/man.cgi?query=hsearch&apropos=0&...
         | says explicitly:
         | 
         | > _The hcreate(), hdestroy(), and hsearch() functions first
         | appeared in AT &T System V UNIX._
         | 
         | which... does seem a bit late for thinking it was a good idea
         | to only support one hash table per process? that was in 01983,
         | 6 years after the vax was introduced and 4 years after the
         | 68000. i mean awk supported arbitrarily many hash tables in a
         | single process in 7th edition unix, even before it had
         | subroutines
        
           | Someone wrote:
           | > i mean awk supported arbitrarily many hash tables in a
           | single process
           | 
           | This API supports that, too, as long as you don't call one of
           | the functions while another call is in progress. You get that
           | for free if your process is single threaded.
           | 
           | https://en.wikipedia.org/wiki/Thread_(computing)#Threading_m.
           | .. says
           | 
           |  _"History of threading models in Unix systems
           | 
           | SunOS 4.x implemented light-weight processes or LWPs. NetBSD
           | 2.x+, and DragonFly BSD implement LWPs as kernel threads (1:1
           | model)"_
           | 
           | According to Wikipedia, SunOS 4.0 is from 1988, NetBSD 2.0
           | from 2004, so I guess chances are good that AT&T System V
           | UNIX didn't support threads in user space programs.
        
             | p_l wrote:
             | Adding threading support is why there was a bunch of
             | interest in using Mach microkernel in Unix systems.
        
             | kimixa wrote:
             | Or a signal handler? Even if there's a single kernel
             | thread, if it can be interrupted while inside one of these
             | functions you can hit the same sort of problem.
             | 
             | Reentrancy was an issue on consumer devices well before
             | multithreading was commonly supported there, after all
        
             | kragen wrote:
             | you seem to be discussing what does or doesn't support
             | multiple _threads_ , but what we were talking about is what
             | does or doesn't support multiple simultaneously existing
             | _hash tables_ , which hcreate() doesn't. i've edited my
             | comment upthread to clarify
             | 
             | (it's also true, as kimixa points out, that a single-
             | threaded process with signal handlers isn't really single-
             | threaded, but i don't think that's really the important
             | consideration in this context)
             | 
             | for what it's worth, it's not very difficult to use alarm()
             | to invoke a context-switching subroutine to get preemptive
             | user-space multithreading on unix without any kernel
             | support. in theory you have to write the context-switching
             | subroutine in assembly language, which isn't difficult at
             | all; here's one i wrote in arm assembly for the arm eabi,
             | for cooperative multithreading:
             | .thumb_func                 .globl einyield
             | einyield:                 push {r0, r4-r11, lr}   @ save
             | all callee-saved regs plus r0                 ldr r0,
             | =current_task_pointer                 ldr r1, [r0]
             | str sp, [r1]            @ save stack pointer in current
             | eintask                 ldr r1, [r1, #4]        @ load
             | pointer to next eintask                 str r1, [r0]
             | ldr sp, [r1]            @ switch to next eintask's stack
             | pop {r0, r4-r11, pc}    @ return into einyielded context
             | there
             | 
             | (from http://canonical.org/~kragen/sw/dev3/einkornix.S)
             | 
             | but in practice you can usually just use longjmp()
             | 
             | preemptive multithreading requires you to save all the
             | registers, not just the callee-saved registers, but so does
             | signal handling, so you can usually just use the signal-
             | handling machinery and use the above code (or its
             | equivalent on your vax or 68000 or whatever) to context-
             | switch between signal-handler stack frames
        
         | tedunangst wrote:
         | Probably started as a function in one program. Somebody copied
         | it into a second program. Somebody wanted it in a third program
         | and copied it into a library.
        
         | loeg wrote:
         | They're really, really old. Dating to System V Unix. At the
         | time it was pretty common to have stateful libc functions.
        
         | layer8 wrote:
         | You can look them up here in System V Interface Definition
         | Issue 2 from 1986: http://www.bitsavers.org/pdf/att/unix/SVID/S
         | ystem_V_Interfac.... It has a note "Future Directions: The
         | restriction on only having one hash search table active at any
         | given time will be removed." Which of course couldn't be done
         | without breaking compatibility.
         | 
         | Most programs at the time probably didn't need more than one
         | hash table, and it made for a simpler interface. (A program
         | could in principle also work around the limitation by storing
         | multiple values per hash table entry.) Most Unix libraries
         | worked with global state at the time, since multi-threading
         | also didn't exist yet. I remember running into the limitation
         | of only being able to have one lexer/parser grammar (via
         | lex/yacc) per program.
        
         | kelnos wrote:
         | [delayed]
        
       | metadat wrote:
       | Is there a command-line interface for this, or is it strictly
       | library-only?
       | 
       | Would be cool if there were a way to point to a memmapped region
       | under /dev/shm or equivalent.
        
         | sph wrote:
         | Type `man redis` or `man sqlite3` for memmapped hash tables
         | with a lot of bells and whistles.
         | 
         | I can't see what would you do with a command line hash table
         | CLI. That's basically a poor man's database.
        
           | metadat wrote:
           | Redis is way too much, but you've got a really good point
           | with SQLite. Thanks!
        
       | pdw wrote:
       | Don't use die.net! The manpages there were last updated 10+ years
       | ago. It's very unfortunate that that site does so well on Google.
        
         | nvy wrote:
         | Is there a better man page site to use instead? I abhor reading
         | in the terminal.
        
           | ivanjermakov wrote:
           | The only other one I'm aware of is Ubuntu manuals:
           | https://manpages.ubuntu.com/manpages/bionic/en/
        
       | Neywiny wrote:
       | I usually turn to C++ when I need such things. Hopefully I
       | remember this exists next time.
        
       ___________________________________________________________________
       (page generated 2024-08-13 23:01 UTC)