Skip to content

Instantly share code, notes, and snippets.

@ethanjli
Last active April 19, 2023 20:00
Show Gist options
  • Save ethanjli/ef2f7453233e0f4a6735fe06c8eb809c to your computer and use it in GitHub Desktop.
Save ethanjli/ef2f7453233e0f4a6735fe06c8eb809c to your computer and use it in GitHub Desktop.
2023-04-18 anglerfish/matchboxscope concurrency discussion pseudocode

currently

when there's an HTTP request for the camera stream:
  serve an MJPEG-over-HTTP stream (multi-part), by:
    as long as the request is open, repeatedly do:
      get the latest frame from the camera by calling esp_camera_fb_get
      send it over HTTP as part of the multi-part response

when there's an HTTP request to upload the latest frame from the camera to Github:
  get the latest frame from the camera by calling esp_camera_fb_get
  upload the frame to Github

when there's an HTTP request for the latest frame (to show on the dashboard):
  get the latest frame from the camera by calling esp_camera_fb_get
  send it over HTTP as the response

when timelapse mode (independent of the MJPEG stream) is enabled:
  get the latest frame from the camera by calling esp_camera_fb_get
  save the frame to the SD card

when esp_camera_fb_get is called, probably:
  the next buffer available to be overwritten is identified (based on a label)
  memory is copied from the camera into that buffer (overwriting the previous contents)
  the oldest buffer is labeled to be overwritten in the next function call
  the pointer into that buffer is returned

option 1 (probably won't work)

we have a constant pointer to a buffer which we'll repeatedly update
we have a read-write lock on that pointer/buffer
whenever frames are needed, repeatedly loop (with a fixed interval):
  get the latest frame from the camera by calling esp_camera_fb_get
  acquire a write lock on our buffer
  copy the latest frame into our buffer
  release the write lock on our buffer
  (now other code can use that pointer, once they acquire a read lock on the buffer)
  
anywhere else that we need the latest frame:
  acquire a read lock on our buffer
  copy that buffer into our own private local buffer
  release the read lock on our buffer
  do things with our own private local buffer

option 2 (simpler, but frames will be acquired independently)

class thread-safe camera:
  we have a constant pointer to a buffer with the latest acquired frame
  we have a read-write lock on that pointer/buffer (see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/pthread.html )
  function update_latest_frame:
    acquire the write lock for the buffer
    get the latest fb pointer from the camera by calling esp_camera_fb_get (we must promise not to call esp_camera_fb_get anywhere else)
    release the write lock for the buffer
    copy the contents of the fb pointer into our buffer
    release the fb pointer for the esp camera
    release the write lock on our buffer
  
anywhere else that we need the latest frame:
  call update_latest_frame
  acquire a read lock on the global buffer
  copy that buffer into our own private local buffer
  release the read lock on the global buffer
  do things with our own private local buffer
@ethanjli
Copy link
Author

without mutexes

array = [0, 0, 0, 0, 0]

thread 1:
  for each array element:
    update the element of the array to 1

thread 2:
  for each array element:
    update the element of the array to 2

Possible results:
array = [1, 1, 1, 1, 1]
array = [2, 2, 2, 2, 2]
array = [1, 2, 1, 1, 2]
array = [2, 2, 2, 1, 1]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment