Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package util

import (
"fmt"
"runtime"
"syscall"
)

Expand Down Expand Up @@ -74,18 +73,7 @@ func GetCurrentProcessTimes() (utime int64, stime int64, err error) {
return
}

// GetTotalMemory gets total system memory on Linux systems
// GetTotalMemory gets total system memory
func GetTotalMemory() uint64 {
switch runtime.GOOS {
case "linux":
// Use sysinfo on Linux
var si syscall.Sysinfo_t
err := syscall.Sysinfo(&si)
if err != nil {
return 0
}
return si.Totalram
default:
return 0
}
return getTotalMemory()
}
34 changes: 34 additions & 0 deletions util/util_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2019-2025 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package util

import (
"syscall"
"unsafe"
)

func getTotalMemory() uint64 {
out, err := syscall.Sysctl("hw.memsize")
if err != nil {
return 0
}
b := []byte(out)
if len(b) < 8 {
b = append(b, 0)
}
return *(*uint64)(unsafe.Pointer(&b[0]))
}
31 changes: 31 additions & 0 deletions util/util_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2019-2025 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package util

import (
"syscall"
)

func getTotalMemory() uint64 {
var si syscall.Sysinfo_t
err := syscall.Sysinfo(&si)
if err != nil {
return 0

Check warning on line 27 in util/util_linux.go

View check run for this annotation

Codecov / codecov/patch

util/util_linux.go#L27

Added line #L27 was not covered by tests
}
// support 32-bit systems where Totalram is uint32
return uint64(si.Totalram) * uint64(si.Unit)
}
32 changes: 32 additions & 0 deletions util/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2019-2025 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package util

import (
"testing"

"github.com/algorand/go-algorand/test/partitiontest"
"github.com/stretchr/testify/require"
)

func TestGetTotalMemory(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

mem := GetTotalMemory()
require.Greater(t, mem, uint64(0))
}
36 changes: 34 additions & 2 deletions util/util_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"math"
"syscall"
"time"
"unsafe"
)

/* misc */
Expand Down Expand Up @@ -70,7 +71,38 @@ func filetimeToDuration(ft *syscall.Filetime) time.Duration {
return time.Duration(n * 100)
}

// GetTotalMemory gets total system memory, returns 0 on Windows
// GetTotalMemory gets total system memory on Windows
func GetTotalMemory() uint64 {
return 0
var memoryStatusEx MemoryStatusEx
memoryStatusEx.dwLength = uint32(unsafe.Sizeof(memoryStatusEx))

if err := globalMemoryStatusEx(&memoryStatusEx); err != nil {
return 0
}
return memoryStatusEx.ullTotalPhys
}

type MemoryStatusEx struct {
dwLength uint32
dwMemoryLoad uint32
ullTotalPhys uint64
ullAvailPhys uint64
ullTotalPageFile uint64
ullAvailPageFile uint64
ullTotalVirtual uint64
ullAvailVirtual uint64
ullAvailExtendedVirtual uint64
}

var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
)

func globalMemoryStatusEx(memoryStatusEx *MemoryStatusEx) error {
ret, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(memoryStatusEx)))
if ret == 0 {
return syscall.GetLastError()
}
return nil
}